• Start

Graph

Knowledge graph patterns

Model entities and relationships as first-class data for traversal, search, and AI workflows using SurrealDB's graph features.

A knowledge graph models your domain as entities (people, products, documents, concepts) connected by typed relationships:

  • document -> cites -> regulation

  • person -> works_at -> organisation

  • symptom -> associated_with -> condition

This structure gives you a map of meaning that you can do the following with:

  • traverse via single- or multi-hop queries

  • enrich with metadata that applies to the relation between one record and another

  • combine with search and AI workflows

In SurrealDB, knowledge graphs are built using: - records as nodes (person, document, concept) - graph relations as edges, created with RELATE

Unlike simple links, edges are first-class records, so you can attach rich metadata to relationships.

A typical pattern looks like this:

DEFINE TABLE person SCHEMAFULL;
DEFINE TABLE organisation SCHEMAFULL;

DEFINE TABLE works_at SCHEMAFULL
TYPE RELATION
FROM person
TO organisation;

-- Require relationship-specific data on each edge
DEFINE FIELD role ON works_at TYPE string;
DEFINE FIELD started_at ON works_at TYPE datetime;

Relationships can then be created using a RELATE statement:

RELATE person:alice->works_at->organisation:acme
SET role = "Engineer",
started_at = time::now();

This lets you query both the connection and the context of the connection.

Use clear table types (person, document, clause) and stable record IDs so relationships remain meaningful over time.

Mapping out queries ahead of time can help make a decision between how coarse- or fine-grained records and edges should be.

For example, you might want to use a single wrote edge to connect a person or similar record to their writing:

SELECT *,
->wrote->blog AS blogs,
->wrote->comment AS comments
FROM person;

SELECT *,
->wrote->(blog, comment) AS all_written
FROM person;

The more generic the type, the greater the chance that you may need to use a filter.

SELECT *,
->(wrote WHERE type = "blog")->item AS blogs,
->(wrote WHERE type = "comment")->item AS comments
FROM person;

A more fine-grained approach with separate blogged and commented edges can be more effective for knowledge-graph and AI use cases, because the relationship semantics are explicit in the graph itself rather than inferred from filters or record types.

SELECT *,
->blogged->blog AS blogs,
->commented->comment AS comments
FROM person;

As multiple edges can always be combined into a single query, you can make your logic as fine-grained as you can conceptually manage without needing to worry about this having an effect on the queries you put together. The only extra addition to such queries is that of the names of the edge tables involved.

SELECT *,
->(blogged, commented)->(blog, comment) AS all_written
FROM person;

You can see these patterns applied in real-world schemas in our sample industry schemas page.

Was this page helpful?