Skip to main content

Quick Tutorial

In this tutorial you'll build a small knowledge base — push a batch of articles, search by meaning, filter by field value, link articles to their authors, and wrap multi-step writes in a transaction.

Every concept introduced here applies equally to agent memory, product catalogs, document stores, or any other data shape you throw at RushDB.

Prerequisites

  • A RushDB account and API token — see Get API Key
  • TypeScript/JavaScript, Python, or any HTTP client

Step 1: Initialize

from rushdb import RushDB

db = RushDB("RUSHDB_API_KEY")

Step 2: Push Records

Use importJson to push a batch of articles in one call. RushDB infers field types automatically and returns record instances you can use immediately.

articles = db.records.create_many(
label="ARTICLE",
data=[
{
"title": "Getting started with graph databases",
"content": "Graph databases model data as nodes and edges, making relationship queries fast and intuitive.",
"tags": ["databases", "graphs"],
"author": "alice"
},
{
"title": "Vector search explained",
"content": "Vector embeddings let you search by semantic meaning rather than exact keywords.",
"tags": ["ai", "search"],
"author": "bob"
},
{
"title": "Building AI agents with persistent memory",
"content": "Agents that remember past interactions can reason across sessions and personalize responses.",
"tags": ["ai", "agents"],
"author": "alice"
}
],
options={ "returnResult": True }
)
Same pattern for agent memory

Swap label: 'ARTICLE' for label: 'MEMORY' and push conversation snippets, tool results, or any structured context. The rest of the tutorial — semantic search, filters, relationships — applies unchanged.

Create an embedding index on the content field, wait for backfill to complete, then search by meaning.

import time

# Create the embedding index

index = db.ai.indexes.create({
"label": "ARTICLE",
"propertyName": "content"
}).data

# Poll until all records are indexed

stats = db.ai.indexes.stats(index["id"]).data
while stats["indexedRecords"] < stats["totalRecords"]:
time.sleep(0.5)
stats = db.ai.indexes.stats(index["id"]).data

# Search by meaning

results = db.ai.search({
"propertyName": "content",
"query": "how do agents remember things across conversations",
"labels": ["ARTICLE"],
"limit": 3
}).data

for result in results:
print(f"[{result['__score']:.3f}] {result['title']}")

# [0.891] Building AI agents with persistent memory

# [0.743] Vector search explained

# [0.612] Getting started with graph databases

Each result includes a __score field (0–1) — cosine similarity between the query embedding and the record's content embedding. Higher is more relevant.

Step 4: Structured Query

Use records.find to filter by exact field values. This is independent of the embedding index.

ai_articles = db.records.find({
"labels": ["ARTICLE"],
"where": {
"tags": { "$in": ["ai"] }
}
})

print([a.data["title"] for a in ai_articles])
# ['Vector search explained', 'Building AI agents with persistent memory']

See the Where clause reference for the full list of operators ($gt, $lt, $contains, $not, and more).

Step 5: Semantic Search with Filter

Combine a where filter with db.ai.search to scope semantic search to a subset of records. RushDB narrows candidates by field values first, then ranks them by cosine similarity.

# Only search within AI-tagged articles
filtered = db.ai.search({
"propertyName": "content",
"query": "memory and learning",
"labels": ["ARTICLE"],
"where": {
"tags": { "$in": ["ai"] }
},
"limit": 5
}).data

for result in filtered:
print(f"[{result['__score']:.3f}] {result['title']}")

note

Without a where clause, RushDB still performs exact semantic ranking over the label-scoped candidates. Adding where reduces the candidate set first, which can improve latency on larger datasets.

Step 6: Relationships

Link each article to an author record. Relationships are first-class in RushDB — they have a type, a direction, and can carry their own properties.

# Create an author record
author = db.records.create(
label="AUTHOR",
data={"name": "Alice", "email": "alice@example.com"}
)

# Attach alice's articles to the author

for article in [a for a in articles if a.data.get("author") == "alice"]:
article.attach(
target=author,
options={"type": "WRITTEN_BY", "direction": "out"}
)

Step 7: Transactions (Optional)

Wrap multiple writes in a transaction to guarantee all-or-nothing atomicity.

with db.tx.begin() as tx:
new_article = db.records.create(
label="ARTICLE",
data={
"title": "Transactions made simple",
"content": "ACID guarantees ensure your data stays consistent even when things fail.",
"tags": ["databases"],
"author": "bob"
},
transaction=tx
)

new_article.attach(
target=author,
options={"type": "WRITTEN_BY", "direction": "out"},
transaction=tx
)
# Commits automatically on exit; rolls back on exception

Next Steps