Skip to main content

GraphStore

Trait GraphStore 

Source
pub trait GraphStore:
    Send
    + Sync
    + 'static {
    // Required methods
    fn ensure_graph(
        &self,
    ) -> impl Future<Output = Result<(), GraphError>> + Send;
    fn query(
        &self,
        cypher: &str,
        params: &HashMap<String, GraphParam>,
    ) -> impl Future<Output = Result<GraphRows, GraphError>> + Send;

    // Provided methods
    fn forget_pids(
        &self,
        pids: &[&str],
    ) -> impl Future<Output = Result<(), GraphError>> + Send { ... }
    fn forget_scope(
        &self,
        scope: &Scope,
    ) -> impl Future<Output = Result<(), GraphError>> + Send { ... }
    fn commit_triples<EM, ER, EdgeR>(
        &self,
        embedder: &EM,
        entities: &ER,
        edges: &EdgeR,
        ctx: &CommitContext,
        triples: &TripleSet,
    ) -> impl Future<Output = Result<usize, CommitError>> + Send
       where EM: EmbeddingModel,
             ER: EntityResolver,
             EdgeR: EdgeResolver { ... }
    fn neighbors(
        &self,
        seed_pids: &[&str],
        scope: &Scope,
        depth: usize,
    ) -> impl Future<Output = Result<GraphContext, GraphError>> + Send { ... }
    fn inspect_scope(
        &self,
        agent_id: Option<&str>,
        org_id: Option<&str>,
        user_id: Option<&str>,
        limit: usize,
    ) -> impl Future<Output = Result<GraphSnapshot, GraphError>> + Send { ... }
}
Expand description

Stores and queries an entity/relationship property graph.

Implementations own the graph-backend connection and confine their writes to a single named graph (see DEFAULT_GRAPH_NAME). The trait methods are async and Send-bound so callers can drive them from any tokio runtime, mirroring crate::vector::VectorIndex.

Required Methods§

Source

fn ensure_graph(&self) -> impl Future<Output = Result<(), GraphError>> + Send

Ensures the configured named graph is reachable.

Idempotent: callers invoke this on startup to fail fast when the backend is unreachable or misconfigured, rather than on first write. FalkorDB creates a graph lazily on first write, so this is a connectivity probe, not a schema-creation step.

§Errors

Returns GraphError::Connection if the backend is unreachable.

Source

fn query( &self, cypher: &str, params: &HashMap<String, GraphParam>, ) -> impl Future<Output = Result<GraphRows, GraphError>> + Send

Runs a parameterized Cypher query against the graph, returning its rows.

The raw escape hatch the write-path and read-path build their operations on. params binds query parameters by name, referenced as $name in the cypher body — the injection-safe way to embed values drawn from user content (entity names, memory ids). Each GraphParam renders to a correctly-quoted Cypher literal (GraphParam::to_cypher_literal), so a value cannot break out of its literal regardless of backend parameter mechanics. Relationship types and labels cannot be parameterized by Cypher and must be sanitized by the caller. Pass an empty map for a query with no parameters. Scalar result values are rendered to String; node/edge/path projections are out of scope until a consumer needs them.

§Errors

Returns GraphError::Query when the backend rejects or fails the query, and GraphError::Connection when the backend is unreachable.

Provided Methods§

Source

fn forget_pids( &self, pids: &[&str], ) -> impl Future<Output = Result<(), GraphError>> + Send

Removes each forgotten pid from the graph, reference-counted.

For each pid: strips it from every edge’s and node’s memory_pids, deletes edges whose array empties, then deletes nodes whose array empties and that have no surviving edges (a node still joined by an other-pid edge is kept). Edges are processed before nodes so a node is never deleted out from under a surviving edge. A pid is a globally-unique memory id, so matching needs no scope guard; the pid binds as a parameter. Idempotent — re-forgetting an absent pid changes nothing.

§Errors

Returns GraphError if the backend rejects a statement.

Source

fn forget_scope( &self, scope: &Scope, ) -> impl Future<Output = Result<(), GraphError>> + Send

Deletes every node and edge in scope — a whole-tenant forget.

The entire scoped subgraph is removed regardless of memory_pids, so this needs no pid list. DETACH DELETE removes each node together with its edges.

§Errors

Returns GraphError if the backend rejects the statement.

Source

fn commit_triples<EM, ER, EdgeR>( &self, embedder: &EM, entities: &ER, edges: &EdgeR, ctx: &CommitContext, triples: &TripleSet, ) -> impl Future<Output = Result<usize, CommitError>> + Send

Commits a source’s resolved triples to the graph, returning the count.

Resolves each triple’s entities (EntityResolver) and edge (EdgeResolver), embeds new nodes ([EmbeddingModel]), then MERGEs the nodes and the (possibly supersession-closing) edge — tagging every element with the source’s pid and scope from ctx. Writes are idempotent, so retrying a partially-failed batch does not double-write. Triples whose subject and object resolve to the same node are skipped.

§Errors

Returns CommitError on the first resolution or write failure.

Source

fn neighbors( &self, seed_pids: &[&str], scope: &Scope, depth: usize, ) -> impl Future<Output = Result<GraphContext, GraphError>> + Send

Returns the graph neighborhood around a set of seed memories.

Seeds from the entities whose memory_pids contains any of seed_pids, then walks current edges (valid_to = null) out to depth hops (clamped to MAX_ENRICHMENT_DEPTH), scope-confined. Returns a flat, deduplicated GraphContext; an empty seed_pids yields an empty context with no query. The read-path enrichment behind .with_graph().

§Errors

Returns GraphError if the backend rejects the traversal.

Source

fn inspect_scope( &self, agent_id: Option<&str>, org_id: Option<&str>, user_id: Option<&str>, limit: usize, ) -> impl Future<Output = Result<GraphSnapshot, GraphError>> + Send

Returns a whole-scope snapshot of the graph for admin inspection.

Reads every entity and relationship matching the partial scope — any of agent_id / org_id / user_id may be None, and an absent dimension imposes no filter, so a fully-None scope dumps the whole graph. This is the one cross-scope read in memoir (an admin views across agents/users/ orgs); the caller’s auth layer gates it. Nodes and edges are each capped at limit (clamped to MAX_INSPECTION_LIMIT); the snapshot’s truncated flag marks when a cap was hit. Both current and superseded edges are returned, each flagged by valid_to, for a temporal view — unlike neighbors, which reads current edges only. Scope values bind as parameters, never interpolated.

§Errors

Returns GraphError if the backend rejects either read.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§