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
- 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]) });
- Reopen the database:
const db2 = GraphDatabase.open('./test.db');
const stats = await db2.stats(); // Bug: Returns 0 nodes
- 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:
- Persistence fix: Uses
GraphDB::with_storage() in open() to properly load persisted nodes and edges
- Embedding persistence: Stores embeddings as JSON properties so they survive persistence/reload
- 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.
Bug Description
Two related issues in
ruvector-graph-nodeNAPI 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, theopen()function createsGraphDB::new()instead of usingGraphDB::with_storage()which properly loads data.Current behavior:
Expected behavior:
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.rsonly handlesPattern::Node, notPattern::Relationship.Current behavior:
Expected behavior:
Steps to Reproduce
Environment
Proposed Fix
I have a working local patch that addresses both issues:
GraphDB::with_storage()inopen()to properly load persisted nodes and edgesexecute_relationship_pattern()function to handlePattern::Relationshipin Cypher queriesThe fix modifies:
crates/ruvector-graph-node/src/lib.rs- NAPI bindingscrates/ruvector-graph/src/graph.rs- Added helper methods (all_nodes(),all_edges())Test results after fix:
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.