Chapter 2
Graph Query Language: SurrealQL Deep Dive
SurrealDB's graph querying power is unleashed through SurrealQL-an expressive, versatile language uniquely suited to navigating, mutating, and extracting insight from complex, connected data. This chapter decrypts SurrealQL's syntax and semantics, shining a light on the advanced operators, traversal logic, and query composability features that set it apart for sophisticated graph work.
2.1 SurrealQL Syntax for Graph Operations
SurrealQL's graph capabilities pivot on a flexible syntax designed to seamlessly unify data definition, traversal, and manipulation within graph structures. The primitives of SurrealQL grant explicit control over nodes and edges while also enabling declarative and procedural query patterns, accommodating various graph processing paradigms. This section unpacks these core primitives and clarifies the distinctions in their usage for graph operations.
Node and Edge Creation
Nodes and edges form the foundational components of any graph. In SurrealQL, nodes are represented as records within a database namespace, identified uniquely by an auto-generated or user-defined identifier, while edges manifest as directed or undirected relationships linking nodes.
Node creation is accomplished with the CREATE keyword and is typically parameterized by a record type and an optional set of named properties:
CREATE vertex:User SET name = "Alice", joined = datetime(); This statement instantiates a node of type User with properties name and joined assigned accordingly. Property types may include primitives such as strings, numbers, booleans, datetimes, or complex objects and arrays.
Edge creation syntactically resembles node creation but employs the RELATE construct to specify directed connections between nodes:
RELATE (u1:User) -> friend -> (u2:User) SET closeness = 0.8; Here, a friend edge is created from node u1 to node u2 with a property closeness indicating the strength of the relationship. The labels u1 and u2 are aliases bound earlier in the query, commonly returned by prior SELECT statements or specified through subqueries.
Edges can also be nondirectional, explicitly indicated by omitting the arrow or using bidirectional syntax. The granularity of edge properties allows encoding rich semantics, facilitating sophisticated queries over relationship attributes.
Property Management for Nodes and Edges
Properties are central to encoding domain semantics and enabling filtered query conditions. SurrealQL employs the SET and UPDATE clauses to define or modify properties of graph elements.
The SET command applies during creation or updates:
UPDATE user:User SET status = "active", last_seen = datetime(); Existing properties may be conditionally overwritten or supplemented, and the type-safe assignment enables insertion of nested objects or arrays to represent complex metadata.
To remove properties, SurrealQL supports the UNSET clause:
UPDATE edge:friendship UNSET closeness; This command deletes the closeness attribute from the specified edge. Comprehensive property management ensures state consistency of both nodes and edges throughout transaction lifecycles.
Graph Traversal and Querying Primitives
Traversing graph structures involves iterating over nodes and navigating edges. SurrealQL offers intuitive syntax to express neighbor expansions, path searches, and pattern matching using both declarative and procedural styles.
The declarative approach employs path expressions embedded within a SELECT context. For example, to retrieve friends of a user and their immediate friends, the syntax is:
SELECT * FROM user:User WHERE name = "Alice" { friends: (-> friend)-User { friends_of_friends: (-> friend)-User } } This query matches User nodes named "Alice" and nests the traversal results of their friend edges (indicated by the arrow -> friend) to obtain direct friends and friends-of-friends, recursively. The embedded object notation expresses hierarchical graph expansion declaratively, automatically resolving the traversal paths.
In contrast, the procedural style leverages control constructs, recursion, or looping in conjunction with aliases and SELECT/FETCH statements for fine-grained traversal steps:
...