From 5226249604999b852551c66bb252f543823c85c4 Mon Sep 17 00:00:00 2001 From: Dhghomon Date: Thu, 17 Oct 2024 12:17:27 +0900 Subject: [PATCH] Rewrite $this parameter usage in DEFINE FIELD --- .../doc-surrealql/statements/define/field.mdx | 70 ++++++++++++++++++- .../doc-surrealql/statements/define/table.mdx | 4 +- .../doc-surrealql/statements/relate.mdx | 4 +- 3 files changed, 71 insertions(+), 7 deletions(-) diff --git a/src/content/doc-surrealql/statements/define/field.mdx b/src/content/doc-surrealql/statements/define/field.mdx index e2a318a6f..ceb7bcc0d 100644 --- a/src/content/doc-surrealql/statements/define/field.mdx +++ b/src/content/doc-surrealql/statements/define/field.mdx @@ -321,19 +321,83 @@ DEFINE FIELD countrycode ON user TYPE string ## Interacting with other fields of the same record -While a `DEFINE TABLE` statement represents a template for any subsequent records to be created, a `DEFINE FIELD` statement pertains to concrete field data of a record. As such, access to both the field itself and its parent record are granted inside `DEFINE FIELD` through the [`$value`](/docs/surrealql/parameters#value) and [`$this`](/docs/surrealql/parameters#parent-this) parameters, respectively. +While a `DEFINE TABLE` statement represents a template for any subsequent records to be created, a `DEFINE FIELD` statement pertains to concrete field data of a record. As such, a `DEFINE FIELD` statement gives access to the record's other fields through their names, as well as the current field through the [`$value`](/docs/surrealql/parameters#value) parameter. ```surql DEFINE TABLE person SCHEMAFULL; DEFINE FIELD first_name ON TABLE person TYPE string VALUE string::lowercase($value); DEFINE FIELD last_name ON TABLE person TYPE string VALUE string::lowercase($value); -DEFINE FIELD name ON TABLE person VALUE $this.first_name + ' ' + $this.last_name; +DEFINE FIELD name ON TABLE person VALUE first_name + ' ' + last_name; // Creates a `person` with the name "bob bobson" CREATE person SET first_name = "BOB", last_name = "BOBSON"; ``` +The `$this` parameter gives access to the entire record on which a field is defined. + +```surql +DEFINE FIELD extra_self ON TABLE person VALUE $this; +CREATE person:one SET name = "Little person", age = 6; +``` + +```surql title="Output" +[ + { + age: 6, + extra_self: { + age: 6, + id: person:one, + name: 'Person' + }, + id: person:one, + name: 'Person' + } +] +``` + +In practice, using `$this` to access the full record is useful when a field is defined as an expression, especially a [future](/docs/surrealql/datamodel/futures) which is computed every time the field is accessed. + +```surql +DEFINE FIELD followers + ON TABLE person + VALUE { (SELECT VALUE <-follows<-person.id FROM ONLY $this) }; + +CREATE person:one, person:two, person:three; + +RELATE person:one->follows->person:three; +SELECT * FROM person:three; + +RELATE person:two->follows->person:three; +SELECT * FROM person:three; +``` + +```surql title="Output of SELECT statements" +-------- Query -------- + +[ + { + followers: [ + person:one + ], + id: person:three + } +] + +-------- Query -------- +[ + { + followers: [ + person:one, + person:two + ], + id: person:three + } +] +``` + +## Order of operations when setting a field's value + As `DEFINE FIELD` statements are computed in alphabetical order, be sure to keep this in mind when using fields that rely on the values of others. The following example is identical to the above except that `full_name` has been chosen for the previous field `name`. The `full_name` field will be calculated after `first_name`, but before `last_name`. @@ -343,7 +407,7 @@ DEFINE TABLE person SCHEMAFULL; DEFINE FIELD first_name ON TABLE person TYPE string VALUE string::lowercase($value); DEFINE FIELD last_name ON TABLE person TYPE string VALUE string::lowercase($value); -DEFINE FIELD full_name ON TABLE person VALUE $this.first_name + ' ' + $this.last_name; +DEFINE FIELD full_name ON TABLE person VALUE first_name + ' ' + last_name; // Creates a `person` with `full_name` of "bob BOBSON", not "bob bobson" CREATE person SET first_name = "Bob", last_name = "Bobson"; diff --git a/src/content/doc-surrealql/statements/define/table.mdx b/src/content/doc-surrealql/statements/define/table.mdx index d8137224f..b9465de0c 100644 --- a/src/content/doc-surrealql/statements/define/table.mdx +++ b/src/content/doc-surrealql/statements/define/table.mdx @@ -225,14 +225,14 @@ CREATE user SET firstName = 'Jamie', lastName = 'Hitchcock', email = 'Jamie.Hitc ## Interaction between fields -While a `DEFINE TABLE` statement represents a template for any subsequent records to be created, a `DEFINE FIELD` statement pertains to concrete field data of a record. As such, access to both the field itself and its parent record are granted inside `DEFINE FIELD` through the `$value` and `$this` parameters, respectively. +While a `DEFINE TABLE` statement represents a template for any subsequent records to be created, a `DEFINE FIELD` statement pertains to concrete field data of a record. As such, a `DEFINE FIELD` statement gives access to the record's other fields through their names, as well as the current field through the [`$value`](/docs/surrealql/parameters#value) parameter. ```surql DEFINE TABLE person SCHEMAFULL; DEFINE FIELD first_name ON TABLE person TYPE string ASSERT string::len($value) < 20; DEFINE FIELD last_name ON TABLE person TYPE string ASSERT string::len($value) < 20; -DEFINE FIELD name ON TABLE person VALUE $this.first_name + ' ' + $this.last_name; +DEFINE FIELD name ON TABLE person VALUE first_name + ' ' + last_name; // Creates a `person` with the name "Bob Bobson" CREATE person SET first_name = "Bob", last_name = "Bobson"; diff --git a/src/content/doc-surrealql/statements/relate.mdx b/src/content/doc-surrealql/statements/relate.mdx index 286123d49..f4e10cb1a 100644 --- a/src/content/doc-surrealql/statements/relate.mdx +++ b/src/content/doc-surrealql/statements/relate.mdx @@ -393,10 +393,10 @@ SELECT id, array::complement(<->sister_of<->city, [id]) AS sister_cities FROM ci ] ``` -When using `RELATE` for this sort of relationship, you may want to define a unique key based on the ordered record IDs involved. +When using `RELATE` for this sort of relationship, you may want to [define a field](/docs/surrealql/statements/define/field) as a unique key based on the ordered record IDs involved. ```surql -DEFINE FIELD key ON TABLE sister_of VALUE array::sort([$this.in, $this.out]); +DEFINE FIELD key ON TABLE sister_of VALUE array::sort([in, out]); DEFINE INDEX only_one_sister_city ON TABLE sister_of FIELDS key UNIQUE; ```