Relationships¶
SurrealEngine supports graph relationships, allowing you to model complex connections between documents. This guide covers reference fields, graph relations, and traversals.
For complete examples, see: example_scripts/relationships_example.py
Reference Fields¶
Simple one-to-many relationships:
from surrealengine import Document, StringField, ReferenceField
class Author(Document):
name = StringField(required=True)
class Meta:
collection = "authors"
class Book(Document):
title = StringField(required=True)
author = ReferenceField("Author", required=True)
class Meta:
collection = "books"
# Create relationships
author = Author(name="Alice")
await author.save()
book = Book(title="Python Guide", author=author.id)
await book.save()
# Fetch with references
books = await Book.objects.fetch("author").all()
print(books[0].author.name) # "Alice"
Graph Relationships¶
Many-to-many relationships using RelationDocument:
from surrealengine import RelationDocument, RelationField, DateTimeField
class User(Document):
name = StringField(required=True)
following = RelationField("Follows", out_ref=True)
followers = RelationField("Follows", in_ref=True)
class Meta:
collection = "users"
class Follows(RelationDocument):
since = DateTimeField(auto_now_add=True)
class Meta:
collection = "follows"
in_doc = "User"
out_doc = "User"
# Create relationship
alice = await User(name="Alice").save()
bob = await User(name="Bob").save()
follow = Follows(in_doc=bob.id, out_doc=alice.id)
await follow.save()
# Query relationships
followers = await Follows.objects.filter(in_doc=bob.id).all()
Graph Traversals¶
Traverse graph relationships:
# Traverse one level
query = User.objects.traverse("->follows->user")
users = await query.all()
# Multi-level traversal with depth
query = User.objects.traverse("->follows->user", max_depth=3)
users = await query.all()
Bidirectional Relations¶
Navigate relationships in both directions:
# Get followers
async def get_followers(user_id: str):
return await Follows.objects.filter(in_doc=user_id).fetch("out_doc").all()
# Get following
async def get_following(user_id: str):
return await Follows.objects.filter(out_doc=user_id).fetch("in_doc").all()
Complex Relationship Queries¶
from surrealengine import Q
# Users following bob and alice
common_followers = await Follows.objects.filter(
Q(in_doc=bob.id) | Q(in_doc=alice.id)
).all()
# Recent followers
recent = await Follows.objects.filter(
in_doc=bob.id
).order_by("-since").limit(10).all()
For more examples, see Tutorial: Building a Blog Application and example_scripts/relationships_example.py