RushDB
Give your agent a memory.
Push any JSON. Get graph relationships and vector search instantly — no schema, no pipeline, no setup.
Start building free →FAQ
RushDB
Push any JSON. Get graph relationships and vector search instantly — no schema, no pipeline, no setup.
Start building free →FAQ
LLM applications naturally fragment into ETL, embedding, graph sync, search indexing, and metadata pipelines. Learn why this happens and how a single ingestion layer can replace.
Every new agent needs a prompt explaining your tables and fields. RushDB lets agents fetch a structured snapshot of the live graph at runtime.
Vector search is genuinely good at one thing: finding records whose meaning is close to a query. Given a question about data retention obligations, a well-tuned embedding model will surface clauses that discuss keeping records, storing data, and retention periods—even when none of those exact words appear in the query.
That capability is valuable. But it answers exactly one question: how similar is this text to that text? It does not answer whether the retrieved clause belongs to the correct jurisdiction, whether the department that owns it has authority over the requesting user, or whether the policy type is retention rather than consent. Those are structural questions, and embeddings have no representation for structure.
This gap becomes a real failure mode in any system where retrieval must respect hard boundaries—compliance routing, multi-tenant knowledge bases, agentic memory systems that need to reason over connected evidence rather than isolated passages. The rest of this article explains why the gap exists, what it costs in practice, and how RushDB's Labeled Meta Property Graph model closes it by treating vector search as one signal inside a structure-aware graph.
An embedding is a point in high-dimensional space. Two points are close when the underlying texts share semantic content. That is the entire information model: proximity, not provenance.
Consider a compliance agent that must answer: "What is our data retention obligation for EU users?" A pure vector search over a policy corpus will rank every clause that discusses retention, regardless of which jurisdiction authored it, which department owns it, or whether it applies to the requesting context. A US-jurisdiction retention policy and an EU-jurisdiction retention policy may be nearly identical in meaning—and therefore nearly identical in vector space—even though serving the wrong one constitutes a compliance failure.
This is not a tuning problem. No amount of prompt engineering or re-ranking fixes it, because the jurisdiction relationship is not encoded in the embedding at all. The embedding captures what the text says; it does not capture where the text sits in the organizational graph.
Three concrete failure modes
retention and one consent. A query for retention policies may return both, because the semantic distance between "keep data for three years" and "keep marketing emails indefinitely" is smaller than it looks to a human.severity: critical or type: retention exist as typed properties on records, but a flat vector store treats metadata as opaque filter fields with no awareness of the graph they inhabit. Filtering on severity in a vector store is possible, but it is application-managed—the store has no concept that severity is a property of a POLICY node that is owned by a DEPARTMENT that belongs to a JURISDICTION.The meaningful distinction is not whether a vector store can store metadata—most can. The distinction is whether connected context is traversed natively as part of the query, or reconstructed in application logic after retrieval. When the graph is reconstructed in application code, every new relationship type requires a new join, a new filter pass, and a new opportunity for the boundary to be missed.
It helps to hold two pictures of the same compliance dataset in mind simultaneously.
The flat vector picture. Every policy clause is a vector. Queries return the nearest vectors. Metadata fields like jurisdiction and department can be attached as payload, and some vector stores support pre-filtering on those fields before ranking. But the relationships between jurisdictions, departments, and policies are not first-class citizens of the data model. They exist only as repeated values in metadata columns, and the query planner has no way to traverse them.
The graph picture. JURISDICTION → DEPARTMENT → POLICY is an explicit edge structure. A POLICY node carries typed properties: type: string, severity: string, clause: string. The graph knows that EU Data Retention Policy is reachable from the EU jurisdiction through the Legal department. A query can start from a jurisdiction constraint, traverse to its policies, and then rank by semantic similarity—in that order, not the reverse.
RushDB implements the second picture through its Labeled Meta Property Graph (LMPG) model, which runs on Neo4j as the underlying storage and transaction engine. Where a plain Labeled Property Graph treats properties as key-value pairs attached to nodes, the LMPG elevates properties into first-class graph structures—HyperProperties—that can themselves carry metadata, participate in indexes, and be queried across the graph. Embedding indexes are one expression of this: a clause property can have a vector index attached to it, making it queryable by semantic similarity while remaining a typed, traversable property inside the graph. RushDB 2.0: Memory Infrastructure for the Agentic Era
The result is that semantic similarity becomes one signal among several, not the only signal. A SearchQuery can express: find POLICY records where type equals retention and severity equals critical—and optionally rank the filtered set by how closely the clause text matches a natural-language query. The structural constraint runs first; the semantic ranking runs over the surviving candidates. Hybrid Retrieval: Filters Plus Semantic Search
The diagram below contrasts the two retrieval paths over the same dataset.
RushDB exposes three capabilities that work together to close the gap between semantic retrieval and structural reasoning.
Embedding indexes as first-class graph concepts. An embedding index in RushDB is not a separate service or a sidecar vector store. It is a policy attached to a string property inside the LMPG. When you create an index on POLICY.clause, RushDB manages the embedding lifecycle on Neo4j—generating vectors for new records, updating them on writes, and exposing the index through db.records.vectorSearch(). You can also bring your own vectors by upserting pre-computed embeddings for a specific property and specifying the similarity function (cosine, euclidean) for that index. Bring Your Own Vectors Either way, the vector index lives inside the same graph that holds the relationships.
Hybrid retrieval through label and property filters. db.records.vectorSearch() accepts a labels array and a where clause alongside the query text or query vector. RushDB narrows the candidate set using those structural constraints first, then ranks the filtered records by cosine or euclidean similarity. Semantic Search (AI and Vectors Search API) This means the semantic ranking never sees records that fail the structural test—the jurisdiction boundary is enforced before similarity is computed, not after.
Live schema discovery. db.ai.getSchema() returns the full graph structure as machine-readable JSON: labels with record counts, properties with inferred types and value ranges, cross-label relationship maps, and per-property vector index metadata. db.ai.getSchemaMarkdown() returns the same information as compact Markdown tables, sized for direct LLM consumption. AI Overview (Semantic Search) An agent that calls getSchemaMarkdown() before constructing a query knows which labels exist, which properties are filterable, which properties have semantic search indexes, and how the labels connect to each other. It can ground its query in the actual data model rather than guessing field names.
These three capabilities compose. An agent can discover the schema, learn that POLICY records have type and severity properties with known value ranges, learn that POLICY is reachable from JURISDICTION through DEPARTMENT, and then issue a query that filters by type and severity before ranking by semantic similarity over clause. The query is both structurally sound and semantically ranked. Features — Vector And Graph Search For Connected AI Retrieval
The following walkthrough uses a small compliance dataset to make the mechanics concrete. The dataset models a single jurisdiction (EU) that owns a Legal department, which in turn owns two policies: one retention policy with critical severity, and one consent policy with medium severity.
The nested JSON import creates the JURISDICTION → DEPARTMENT → POLICY edge structure automatically. RushDB infers the labels from the JSON keys and creates typed records for each node.
{
"JURISDICTION": {
"name": "EU",
"region": "Europe",
"DEPARTMENT": [
{
"name": "Legal",
"POLICY": [
{
"title": "EU Data Retention Policy",
"clause": "We retain user personal data for exactly 3 years under GDPR guidelines.",
"type": "retention",
"severity": "critical"
},
{
"title": "EU Marketing Consent Policy",
"clause": "Keep marketing emails indefinitely unless the user opts out.",
"type": "consent",
"severity": "medium"
}
]
}
]
}
}
The suggestTypes: true option tells RushDB to infer property types from the values—severity becomes a string property with known values critical and medium, not an opaque blob.
Before issuing any query, call getSchema() to see what the graph actually contains. This is the step that separates structure-aware retrieval from blind vector search.
schema = db.ai.get_schema({})
print(json.dumps(schema.data, indent=2))
The response shows three labels (JURISDICTION, DEPARTMENT, POLICY), their record counts, the typed properties on each label, the value ranges for those properties, and the directed relationships between labels. The POLICY label has four string properties: clause, severity, title, and type. The Semantic Search column in the Markdown variant would show — for each property until an embedding index is created on clause—at which point it would show the index source type, similarity function, and dimension count.
For an LLM agent, the Markdown variant is more token-efficient:
schema_markdown = db.ai.get_schema_markdown({})
print(schema_markdown.data)
The schema snapshot is cached for up to one hour. If records are added or removed between calls, the cached snapshot may not reflect the latest state; the cache refreshes automatically on the next cycle.
With the schema in hand, the agent knows that POLICY records have a type property with values consent and retention, and a severity property with values critical and medium. A query for critical retention policies can be expressed as exact filters—no semantic ambiguity, no risk of returning the consent policy.
records = db.records.find({
"labels": [
"POLICY"
],
"where": {
"type": "retention",
"severity": "critical"
},
"limit": 10
})
print(json.dumps({"total": records.total, "data": [record.data for record in records.data]}, indent=2))
When an embedding index exists on POLICY.clause, the same SearchQuery shape extends naturally to hybrid retrieval: add a query field with the natural-language text, and RushDB ranks the filtered candidates by semantic similarity before returning them. The structural filter runs first; the semantic ranking runs over the survivors. Hybrid Retrieval: Filters Plus Semantic Search
The query above—labels: ["POLICY"], where: { type: "retention", severity: "critical" }—returns exactly one record:
{
"data": [
{
"__label": "POLICY",
"clause": "We retain user personal data for exactly 3 years under GDPR guidelines.",
"severity": "critical",
"title": "EU Data Retention Policy",
"type": "retention"
}
],
"total": 1
}
The EU Marketing Consent Policy is absent. Its type is consent and its severity is medium; it fails both filters. The structural constraint did its job before any similarity ranking was needed.
The total: 1 in the response confirms that the filter is applied server-side, not post-hoc in application code. The searchQuery echo in the response shows the exact query that was executed, which is useful for debugging and audit logging.
Captured from a run against an isolated RushDB project in Python and TypeScript; volatile record identifiers are normalized.
Use the discovered fields in a structured query
{
"data": [
{
"__label": "POLICY",
"clause": "We retain user personal data for exactly 3 years under GDPR guidelines.",
"severity": "critical",
"title": "EU Data Retention Policy",
"type": "retention"
}
],
"searchQuery": {
"labels": [
"POLICY"
],
"limit": 10,
"where": {
"severity": "critical",
"type": "retention"
}
},
"total": 1
}
The compliance scenario is deliberately small, but the architectural pattern scales to the problems that make pure vector search insufficient in production.
Agents can ground queries in the actual data model. When an agent calls getSchemaMarkdown() at the start of a session, it receives a token-efficient summary of every label, every typed property, every value range, and every relationship in the graph. It can use that summary to construct queries that reference real field names and real values—not hallucinated ones. The schema is live: it reflects the current state of the graph, not a static documentation page that may have drifted. AI Overview (Semantic Search)
Semantic search becomes a ranking signal, not a retrieval boundary. In a pure vector system, the embedding is the only retrieval mechanism. Everything that matters—jurisdiction, department, policy type, severity—must be encoded into the embedding or stored as metadata and filtered in application code. In RushDB, those dimensions are first-class properties in the graph. Semantic similarity ranks within a structurally correct candidate set, rather than competing with structural correctness for the same retrieval slot. Semantic Search (AI and Vectors Search API)
The same backend serves multiple retrieval patterns. Agent recall, knowledge-base search, faceted filtering, and operational dashboards can all query the same RushDB project. A faceted UI filters by severity and type using exact where clauses. An agent uses db.ai.search() for natural-language queries that RushDB converts into a SearchQuery using the live schema. A RAG pipeline uses db.records.vectorSearch() for direct similarity ranking over an embedding index. None of these require a separate vector store, a separate metadata database, or application-layer join logic. Features — Vector And Graph Search For Connected AI Retrieval Features — RushDB
Bring Your Own Vectors remains an option. Teams that already generate embeddings with a specific model—or that need a model not covered by RushDB's managed indexes—can upsert pre-computed vectors for any property and specify the similarity function for that index. Bring Your Own Vectors The structural query layer works identically regardless of whether the vectors were managed or externally supplied.
One caveat worth naming. Schema grounding reduces the risk of querying nonexistent fields or using wrong value types, but it does not make queries semantically correct by construction. An agent that misreads the schema or constructs a logically wrong filter will still get wrong results—just wrong results that are structurally valid. Schema discovery is a tool for reducing a class of errors, not eliminating all retrieval errors.
Embeddings are a powerful tool for ranking text by meaning. They are not a data model. They have no representation for the relationships between records, the types of properties, the cardinality of edges, or the organizational boundaries that determine whether a retrieved result is actually correct.
RushDB's Labeled Meta Property Graph model treats those structural dimensions as first-class citizens—stored and traversed on Neo4j, exposed through a unified REST and SDK interface, and queryable in combination with semantic similarity through a single SearchQuery. The schema APIs make the live graph structure available to agents and applications without requiring them to maintain a separate schema registry or guess field names.
The result is a retrieval system that can answer both questions at once: is this text semantically relevant? and does this record belong to the correct part of the graph? For systems where the second question has hard consequences—compliance, multi-tenant isolation, policy routing—the combination is not a convenience. It is a requirement.