Skip to main content

Connect Records

Relationships are the connections that link records together, creating a graph structure. They have a type (a string label you define), a direction, and optional user-defined edge properties.

RushDB supports three categories of relationships:

TypeCreated byDescription
__RUSHDB__RELATION__DEFAULT__Auto, on importLinks parent → child records in nested JSON
__RUSHDB__RELATION__VALUE__Auto, internallyConnects property nodes to record nodes (read-only)
Custom ("STARS_IN", "DIRECTED_BY", etc.)YouDomain-specific, manually created

Attach Records

db.records.attach()

# Single target
db.records.attach(
source=movie,
target=actor,
options={"type": "STARS_IN", "direction": "out", "properties": {"role": "lead"}}
)

# One-to-many (target list)
db.records.attach(
source=movie,
target=[actor1, actor2, actor3],
options={"type": "STARS_IN"}
)

Detach Records

db.records.detach()

db.records.detach(
source=movie,
target=actor,
options={"type": "STARS_IN"}
# Omit "type" to detach all relationship types
)

List Relationships

db.relationships.find()

# Relationship search: where filters edge type/properties
relationships = db.relationships.find(
search_query={
"source": {"labels": ["MOVIE"], "where": {"title": "Inception"}},
"target": {"labels": ["ACTOR"], "where": {"country": "USA"}},
"where": {"type": "STARS_IN", "role": "lead"}
}
)

# With pagination
page = db.relationships.find(
search_query={"source": {"labels": ["MOVIE"]}},
pagination={"limit": 50, "skip": 0}
)

db.relationships.find().where is edge-scoped. Use source and target for record predicates. To filter records by traversing relationships, use db.records.find() with $relation as shown below.

Edge properties are stored directly on relationship edges. They are filterable through relationships.find() and summarized in ontology relationship sections, but they are not promoted to Record Property nodes and are not semantically indexed. See Relationship Properties for storage semantics, the full operator set, and modeling guidance.


Direction Reference

directionGraph pattern
out(source) -[:TYPE]-> (target)
in(source) <-[:TYPE]- (target)

Search by Relationship

Use $relation inside a where clause to filter records through their graph connections. The nested key is the label of the related record; $relation constrains which relationship edge to follow.

Any relationship type

Omit $relation to traverse any edge connecting the two labels:

# Find MOVIEs connected to an ACTOR named "Timothée Chalamet" — any relationship type
result = db.records.find({
"labels": ["MOVIE"],
"where": {
"ACTOR": {
"name": "Timothée Chalamet"
}
}
})

Filter by relationship type

Pass $relation as a string to restrict traversal to a specific relationship type. This produces a direction-agnostic Cypher pattern (-[:TYPE]-) that matches the edge regardless of its stored direction — use the full object form (below) to also constrain direction:

result = db.records.find({
"labels": ["MOVIE"],
"where": {
"ACTOR": {
"$relation": "STARS_IN",
"country": "USA"
}
}
})

Filter by relationship type and direction

Use the full object form when direction matters:

FieldTypeDescription
typestringRelationship type label
direction"in" | "out"Edge direction relative to the root record
# Find MOVIEs where an ACTOR is connected via an incoming STARS_IN edge
# i.e. (ACTOR) -[:STARS_IN]-> (MOVIE)
result = db.records.find({
"labels": ["MOVIE"],
"where": {
"ACTOR": {
"$relation": {"type": "STARS_IN", "direction": "in"},
"country": "USA"
}
}
})

Multi-hop traversal

Nest $relation filters to traverse multiple relationship levels in a single query:

# Companies → Engineering departments → projects with budget over 10k
result = db.records.find({
"labels": ["COMPANY"],
"where": {
"name": "Acme Corp",
"DEPARTMENT": {
"$relation": "HAS_DEPARTMENT",
"name": "Engineering",
"PROJECT": {
"$relation": "HAS_PROJECT",
"budget": {"$gte": 10000}
}
}
}
})

→ For the full operator reference including $alias, $id, and logical grouping, see Where Operators — Relationship Queries.


In a Transaction

tx = db.tx.begin()
try:
movie = db.records.create(
label="MOVIE", data={"title": "Dune"}, transaction=tx
)
actor = db.records.create(
label="ACTOR", data={"name": "Timothée Chalamet"}, transaction=tx
)
db.records.attach(
source=movie,
target=actor,
options={"type": "STARS_IN"},
transaction=tx
)
tx.commit()
except Exception:
tx.rollback()
raise

Via Record Instance

# Record instance methods — equivalent to db.records.attach/detach
movie.attach(
target=actor,
options={"type": "STARS_IN", "direction": "out"}
)

movie.detach(
target=actor,
options={"type": "STARS_IN"}
)

See also

  • Bulk Relationships — connect/disconnect many records at once by key match or many-to-many
  • Import Data — nested JSON auto-creates relationships
  • Transactions — ACID guarantees for multi-step operations