• Start

Language Primitives

Record links

One of the most powerful features of SurrealDB is the ability to traverse from record-to-record without the need for traditional SQL JOINs. Each record ID points directly to a specific record in the database.

One of the most powerful features of SurrealDB is the ability to traverse from record-to-record without the need for traditional SQL JOINs. Each record ID points directly to a specific record in the database, without needing to run a table scan query. Record IDs can be stored within other records, allowing them to be linked together.

When you create a record without specifying the id, then a randomly generated id is created and used for the record id.

/**[test]

[[test.results]]
value = "[{ id: person:lva0fwhgqxuk0m88ktn1, name: 'Tobie' }]"
skip-record-id-key = true

*/

CREATE person SET name = 'Tobie';

-- person:aio58g22n3upq16hsani

It's also possible to specify a specific record id when creating or updating records.

/**[test]

[[test.results]]
value = "[{ id: person:tester, name: 'Tobie' }]"

*/

CREATE person:tester SET name = 'Tobie';

-- person:tester

Because Record IDs are their own datatype in SurrealQL, you are able to select directly off of them.

/**[test]

[[test.results]]
value = "[{ email: 'tobie@surrealdb.com', id: person:tobie, name: 'Tobie', opts: { enabled: true } }]"

[[test.results]]
value = "{ email: 'tobie@surrealdb.com', id: person:tobie, name: 'Tobie', opts: { enabled: true } }"

[[test.results]]
value = "{ email: 'tobie@surrealdb.com', name: 'Tobie' }"

*/

CREATE person:tobie SET name = 'Tobie', email = 'tobie@surrealdb.com', opts.enabled = true;

-- Select the whole record
person:tobie.*;

-- Select specific fields
person:tobie.{ name, email };

Records ids can be stored directly within other records, either as top-level properties, or nested within objects or arrays.

/**[test]

[[test.results]]
value = "[{ friends: [person:tobie, person:simon], id: person:jaime, name: 'Jaime' }]"

[[test.results]]
value = "[{ friends: [person:simon, person:marcus], id: person:tobie, name: 'Tobie' }]"

[[test.results]]
value = "[{ friends: [person:jaime, person:tobie], id: person:simon, name: 'Simon' }]"

[[test.results]]
value = "[{ friends: [person:tobie], id: person:marcus, name: 'Marcus' }]"

*/

CREATE person:jaime SET name = 'Jaime', friends = [person:tobie, person:simon];
CREATE person:tobie SET name = 'Tobie', friends = [person:simon, person:marcus];
CREATE person:simon SET name = 'Simon', friends = [person:jaime, person:tobie];
CREATE person:marcus SET name = 'Marcus', friends = [person:tobie];

Nested field traversal can be used to fetch the properties from the remote records, as if the record was embedded within the record being queried.

SELECT friends.name FROM person:tobie;
[
	{
		friends: {
			name: ["Simon", "Marcus"]
		}
	}
]

There is no limit to the number of remote traversals that can be performed in a query. Using . dot notation, SurrealDB does not differentiate between nested object properties, or remote records, and will fetch remote records asynchronously when needed for a query.

SELECT friends.friends.friends.name FROM person:tobie;
[
	{
		friends: {
			friends: {
				friends: {
					name: [
						[ ["Tobie", "Simon"], ["Simon", "Marcus"] ],
						[ ["Simon", "Marcus"] ]
					]
				}
			}
		}
	}
]

Was this page helpful?