Skip to content

Bug: GraphDatabase.open() doesn't load persisted data; Cypher relationship traversals return empty results #64

@carheart

Description

@carheart

Bug Description

Two related issues in ruvector-graph-node NAPI bindings:

Issue 1: Persistence doesn't reload data

GraphDatabase.open(path) creates empty in-memory structures instead of loading persisted data.

Root cause: In crates/ruvector-graph-node/src/lib.rs, the open() function creates GraphDB::new() instead of using GraphDB::with_storage() which properly loads data.

Current behavior:

const db = GraphDatabase.open('./my.db');
const stats = await db.stats();  // Returns { totalNodes: 0 } even though file has data

Expected behavior:

const db = GraphDatabase.open('./my.db');
const stats = await db.stats();  // Returns { totalNodes: 2 } with persisted data loaded

Issue 2: Cypher relationship traversals return empty results

Queries like MATCH (a)-[:TYPE]->(b) return 0 results even when edges exist.

Root cause: The query execution in lib.rs only handles Pattern::Node, not Pattern::Relationship.

Current behavior:

await db.query('MATCH (n:Person) RETURN n');  // Works ✅
await db.query('MATCH (a)-[:KNOWS]->(b) RETURN a, b');  // Returns empty ❌

Expected behavior:

await db.query('MATCH (a)-[:KNOWS]->(b) RETURN a, b');  // Returns matching nodes and edges ✅

Steps to Reproduce

  1. Create a database with persistence:
const db = new GraphDatabase({ storagePath: './test.db' });
await db.createNode({ id: 'alice', embedding: new Float32Array([1,0,0,0]), labels: ['Person'] });
await db.createNode({ id: 'bob', embedding: new Float32Array([0,1,0,0]), labels: ['Person'] });
await db.createEdge({ from: 'alice', to: 'bob', description: 'KNOWS', embedding: new Float32Array([0.5,0.5,0,0]) });
  1. Reopen the database:
const db2 = GraphDatabase.open('./test.db');
const stats = await db2.stats();  // Bug: Returns 0 nodes
  1. Query relationships:
const result = await db.query('MATCH (a:Person)-[:KNOWS]->(b:Person) RETURN a, b');
// Bug: Returns empty results

Environment

  • ruvector version: 0.1.21
  • Node.js: v22.x
  • OS: Linux (also tested on other platforms)

Proposed Fix

I have a working local patch that addresses both issues:

  1. Persistence fix: Uses GraphDB::with_storage() in open() to properly load persisted nodes and edges
  2. Embedding persistence: Stores embeddings as JSON properties so they survive persistence/reload
  3. Relationship queries: Adds execute_relationship_pattern() function to handle Pattern::Relationship in Cypher queries

The fix modifies:

  • crates/ruvector-graph-node/src/lib.rs - NAPI bindings
  • crates/ruvector-graph/src/graph.rs - Added helper methods (all_nodes(), all_edges())

Test results after fix:

Persistence test: PASS ✅
Relationship query test: PASS ✅

Happy to submit a PR with the complete fix if this approach is acceptable. The changes are backward-compatible and don't modify the public API.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions