JavaScript API Reference¶
CongraphDB provides a JavaScript-native API as an alternative to Cypher for developers who prefer a programmatic interface. This API is particularly useful for:
- Simple CRUD operations on nodes and edges
- Application-specific data access patterns
- Developers who prefer method calls over query strings
- LevelGraph users seeking a familiar API
- Type safety with TypeScript
Quick Start¶
const { Database, CongraphDBAPI } = require('congraphdb');
// Initialize
const db = new Database('./my-graph.cgraph');
await db.init();
const api = new CongraphDBAPI(db);
// Create nodes
const alice = await api.createNode('User', { name: 'Alice', age: 30 });
const bob = await api.createNode('User', { name: 'Bob', age: 25 });
// Create relationships
await api.createEdge(alice._id, 'KNOWS', bob._id, { since: 2020 });
// Query with pattern matching
const friends = await api.find({
subject: alice._id,
predicate: 'KNOWS',
object: api.v('friend')
});
// Fluent traversal API
const friendsOfFriends = await api.nav(alice._id)
.out('KNOWS')
.out('KNOWS')
.values();
// Cleanup
await api.close();
await db.close();
CongraphDBAPI¶
The main API class providing access to all graph operations.
Constructor¶
Creates a new CongraphDBAPI instance. Accepts either a Database or Connection object.
Node Operations¶
createNode(label, properties)¶
Create a new node with the given label and properties.
const node = await api.createNode('Person', {
name: 'Alice',
age: 30,
email: 'alice@example.com'
});
// Returns: { _id: '...', name: 'Alice', age: 30, email: '...' }
getNode(id)¶
Get a node by its ID.
getNodesByLabel(label)¶
Get all nodes with a specific label.
updateNode(id, properties)¶
Update a node's properties.
const updated = await api.updateNode('node-id', {
age: 31,
lastSeen: Date.now()
});
// Returns the updated node
deleteNode(id, detach)¶
Delete a node.
// Delete node (fails if it has relationships)
await api.deleteNode('node-id');
// Delete node and all relationships
await api.deleteNode('node-id', true);
Edge Operations¶
createEdge(fromId, relType, toId, properties)¶
Create a new relationship between nodes.
const edge = await api.createEdge(
'alice-node-id', // from node
'KNOWS', // relationship type
'bob-node-id', // to node
{ since: 2020 } // edge properties (optional)
);
// Returns: { _id: '...', _type: 'KNOWS', _from: '...', _to: '...', since: 2020 }
getEdge(id)¶
Get an edge by its ID.
getEdges(options)¶
Get edges with optional filtering.
// All edges from a node
const outgoing = await api.getEdges({ from: 'node-id' });
// All edges to a node
const incoming = await api.getEdges({ to: 'node-id' });
// All edges of a specific type
const knowsEdges = await api.getEdges({ type: 'KNOWS' });
// Combined filters
const results = await api.getEdges({
from: 'node-id',
type: 'KNOWS'
});
updateEdge(id, properties)¶
Update an edge's properties.
deleteEdge(id)¶
Delete an edge.
Pattern Matching¶
find(pattern, options)¶
Execute a pattern matching query.
// Simple pattern
const friends = await api.find({
subject: alice._id,
predicate: 'KNOWS',
object: api.v('friend')
});
// Returns: [{ friend: { name: 'Bob', ... } }, ...]
// With WHERE filter
const results = await api.find({
subject: alice._id,
predicate: 'KNOWS',
object: api.v('friend')
}, {
where: 'friend.age > 25'
});
// With multiple variables
const results = await api.find({
subject: api.v('person'),
predicate: 'KNOWS',
object: api.v('friend')
});
v(name)¶
Create a variable for pattern matching results.
const friendVar = api.v('friend');
const results = await api.find({
subject: alice._id,
predicate: 'KNOWS',
object: friendVar
});
Navigation¶
nav(startId)¶
Create a Navigator for fluent graph traversal.
See Navigator section below for full traversal API.
Transactions¶
transaction(fn)¶
Execute operations in a transaction.
await api.transaction(async (txApi) => {
const alice = await txApi.createNode('Person', { name: 'Alice' });
const bob = await txApi.createNode('Person', { name: 'Bob' });
await txApi.createEdge(alice._id, 'KNOWS', bob._id);
// All operations commit if no error is thrown
});
Raw Queries¶
query(cypher)¶
Execute a raw Cypher query.
const result = await api.query(`
MATCH (p:Person)-[:KNOWS]->(f:Person)
RETURN p.name, f.name
`);
const rows = await result.getAll();
Schema API¶
The api.schema object provides JavaScript-native methods for managing database schema.
createNodeTable(name, options)¶
Create a new node table with specified properties.
await api.schema.createNodeTable('User', {
properties: {
id: 'string',
name: 'string',
age: 'int64',
email: 'string'
},
primaryKey: 'id'
});
createRelTable(name, options)¶
Create a new relationship table.
await api.schema.createRelTable('KNOWS', {
from: 'User',
to: 'User',
properties: {
since: 'int64',
strength: 'double'
}
});
createIndex(tableName, columns)¶
Create an index on one or more columns.
// Single column index
await api.schema.createIndex('User', 'email');
// Composite index
await api.schema.createIndex('Post', ['title', 'createdAt']);
getTables()¶
List all tables in the database.
const tables = await api.schema.getTables();
for (const table of tables) {
console.log(`Table: ${table.name} (${table.table_type})`);
}
dropTable(name)¶
Drop a table from the database.
ensureSchema(schema)¶
Idempotent schema creation - safe to run multiple times. Useful for migrations.
const schema = {
nodeTables: [
{
name: 'User',
properties: { id: 'string', name: 'string', age: 'int64' },
primaryKey: 'id'
}
],
relTables: [
{
name: 'KNOWS',
from: 'User',
to: 'User',
properties: { since: 'int64' }
}
]
};
await api.schema.ensureSchema(schema);
See also: Schemas Guide for complete schema documentation including Cypher DDL syntax and supported property types.
Execute a raw Cypher query.
const result = await api.query(`
MATCH (p:Person)-[:KNOWS]->(f:Person)
RETURN p.name, f.name
`);
const rows = await result.getAll();
Utilities¶
close()¶
Close the API and cleanup resources.
OCC Methods (v0.1.8+)¶
Optimistic Concurrency Control methods for high-concurrency scenarios.
commitWithOccSync(maxRetries)¶
Commit the current transaction with automatic retry on OCC conflicts.
conn.beginTransaction();
try {
await conn.query(`MATCH (u:User {id: 'alice'}) SET u.balance = u.balance - 100`);
await conn.query(`MATCH (u:User {id: 'bob'}) SET u.balance = u.balance + 100`);
// Commit with automatic retry on conflict
await conn.commitWithOccSync(10); // max 10 retries
} catch (error) {
conn.rollback();
throw error;
}
executeWithRetrySync(fn, maxRetries)¶
Execute operations with automatic retry on OCC conflicts.
const result = await conn.executeWithRetrySync(5, () => {
return conn.query(`
MATCH (u:User {id: $id})
SET u.lastLogin = $ts
RETURN u
`, { id: 'alice', ts: Date.now() });
});
getOccStatistics()¶
Get OCC conflict metrics for monitoring concurrency patterns.
const stats = await conn.getOccStatistics();
console.log(stats);
// {
// successful_transactions: 1250,
// failed_transactions: 5,
// conflicts_detected: 23,
// total_retries: 18,
// max_retry_count: 3,
// conflict_rate: 1.84 // percentage
// }
resetOccStatistics()¶
Reset OCC statistics counters.
getVersionCacheSize()¶
Get the current size of the OCC version cache.
const cacheSize = await conn.getVersionCacheSize();
console.log(`Version cache entries: ${cacheSize}`);
clearVersionCache()¶
Clear the OCC version cache.
Graph RAG APIs (v0.2.1+)¶
Optimized entry points for common Graph RAG workflows, available on the Connection class.
lightRagSearch(queryVector, localK, globalK, entityTable, factTable)¶
Performs simultaneous vector search on two tables (typically Entity and Fact) to provide both local and global context in a single native call.
const results = await conn.lightRagSearch(
queryEmbedding, // Float32Array or Array<number>
10, // localK (Entities)
15, // globalK (Facts)
'Entity', // entityTable name
'Fact' // factTable name
);
console.log(results.local_results); // Array of Entity nodes
console.log(results.global_results); // Array of Fact nodes
retrieveContextPaths(entityIds, maxDepth)¶
Finds connections and context paths between a set of matched entities.
const context = await conn.retrieveContextPaths(
['entity_1', 'entity_2', 'entity_3'],
3 // maxDepth
);
console.log(context.paths); // Graph context for LLM prompt
VectorStore API (v0.2.1+)¶
A high-level, LanceDB-inspired API for vector similarity search and document management.
Initialization¶
const { createVectorStore } = require('congraphdb');
const store = createVectorStore('./vector.cgraph', {
enableCompression: true
});
await store.init();
Table Management¶
createTable(name, schema)¶
await store.createTable('Documents', {
vectorProperty: 'embedding',
vectorDim: 1536,
properties: {
title: 'string',
content: 'string',
category: 'string'
},
indexOptions: {
metric: 'cosine',
m: 16,
efConstruction: 200
}
});
Data Operations¶
add(tableName, documents)¶
await store.add('Documents', [
{
title: 'Doc 1',
content: '...',
embedding: [0.1, 0.2, ...]
},
{
title: 'Doc 2',
content: '...',
embedding: [0.3, 0.4, ...]
}
]);
addBulk(tableName, documents, options)¶
Optimized for inserting thousands of documents.
Search Operations¶
search(tableName, queryVector, options)¶
const results = await store.search('Documents', queryVec, {
limit: 5,
filter: { category: 'AI' }
});
// Returns documents with _distance and _score metadata
searchBatch(tableName, queryVectors, options)¶
Parallel vector search for multiple queries.
Utilities¶
checkpoint()¶
Force persist pending changes to disk (WAL flush).
close()¶
Safely close the store and flush all data.
See also: OCC Guide for complete OCC documentation.
Navigator¶
Fluent graph traversal API (LevelGraph-compatible).
Creating a Navigator¶
Traversal Methods¶
out(relType)¶
Traverse outgoing relationships.
in(relType)¶
Traverse incoming relationships.
both(relType)¶
Traverse relationships in both directions.
Chaining Traversals¶
// Two-hop traversal
const friendsOfFriends = await api.nav(alice._id)
.out('KNOWS')
.out('KNOWS')
.values();
// Three-hop traversal
const threeHop = await api.nav(alice._id)
.out('KNOWS')
.out('KNOWS')
.out('KNOWS')
.values();
Filtering¶
where(condition)¶
Filter results by condition.
// String condition (Cypher-style)
const nycFriends = await api.nav(alice._id)
.out('KNOWS')
.where('city = "NYC"')
.values();
// Function condition (JavaScript)
const youngFriends = await api.nav(alice._id)
.out('KNOWS')
.where(f => f.age < 30)
.values();
limit(n)¶
Limit the number of results.
Path Finding¶
to(targetId)¶
Find the shortest path to a target node.
Getting Results¶
values()¶
Get matching nodes as an array.
paths()¶
Get full paths (including intermediate nodes and edges).
count()¶
Count matching nodes.
Synchronous Methods¶
All traversal methods have synchronous variants:
const nodes = api.nav(alice._id)
.out('KNOWS')
.valuesSync();
const paths = api.nav(alice._id)
.out('KNOWS')
.pathsSync();
const count = api.nav(alice._id)
.out('KNOWS')
.countSync();
Async Iteration¶
Navigate using for await...of:
LevelGraph Compatibility¶
The Navigator API provides LevelGraph-compatible aliases:
// LevelGraph-style methods
const results = await api.nav(alice._id)
.archOut('KNOWS') // Alias for .out()
.solutions(); // Alias for .values()
Pattern¶
Represents a graph pattern for matching queries.
Constructor¶
Using Patterns¶
const pattern = new Pattern({
subject: api.v('person'),
predicate: 'KNOWS',
object: api.v('friend')
});
const results = await api.find(pattern);
Variable¶
Represents a variable in pattern matching.
Creating Variables¶
Using Variables¶
const results = await api.find({
subject: api.v('person'),
predicate: 'KNOWS',
object: api.v('friend')
});
// Results are keyed by variable name
results[0].person; // First matching person
results[0].friend; // First matching friend
Type Definitions¶
class CongraphDBAPI {
constructor(dbOrConnection: Database | Connection)
// Node operations
createNode(label: string, properties: object): Promise<Node>
getNode(id: string): Promise<Node | null>
getNodesByLabel(label: string): Promise<Node[]>
updateNode(id: string, properties: object): Promise<Node>
deleteNode(id: string, detach?: boolean): Promise<boolean>
// Edge operations
createEdge(fromId: string, relType: string, toId: string, properties?: object): Promise<Edge>
getEdge(id: string): Promise<Edge | null>
getEdges(options?: {from?: string, to?: string, type?: string}): Promise<Edge[]>
updateEdge(id: string, properties: object): Promise<Edge>
deleteEdge(id: string): Promise<boolean>
// Pattern matching
find(pattern: Pattern | object, options?: object): Promise<any[]>
v(name: string): Variable
nav(startId: string): Navigator
// Transactions
transaction(fn: (api: CongraphDBAPI) => Promise<T>): Promise<T>
// Raw queries
query(cypher: string): Promise<QueryResult>
// Schema API
schema: {
createNodeTable(name: string, options: NodeTableOptions): Promise<void>
createRelTable(name: string, options: RelTableOptions): Promise<void>
createIndex(tableName: string, columns: string | string[]): Promise<void>
getTables(): Promise<TableInfo[]>
dropTable(name: string): Promise<void>
ensureSchema(schema: SchemaDefinition): Promise<void>
}
// Utilities
close(): Promise<void>
}
interface NodeTableOptions {
properties: Record<string, PropertyType>
primaryKey: string
}
interface RelTableOptions {
from: string
to: string
properties?: Record<string, PropertyType>
}
type PropertyType =
| 'bool' | 'int8' | 'int16' | 'int32' | 'int64'
| 'uint8' | 'uint16' | 'uint32' | 'uint64'
| 'float' | 'double'
| 'string' | 'blob'
| 'date' | 'timestamp' | 'interval'
| `vector[${number}]`
interface SchemaDefinition {
nodeTables?: NodeTableOptions[]
relTables?: RelTableOptions[]
}
class Navigator {
// Traversal
out(relType: string): Navigator
in(relType: string): Navigator
both(relType: string): Navigator
// Filtering
where(condition: string | Function): Navigator
limit(n: number): Navigator
// Path finding
to(targetId: string): Navigator
// Results
values(): Promise<Node[]>
paths(): Promise<Path[]>
count(): Promise<number>
// Synchronous variants
valuesSync(): Node[]
pathsSync(): Path[]
countSync(): number
// LevelGraph compatibility
archOut(relType: string): Navigator
archIn(relType: string): Navigator
solutions(): Promise<Node[]>
// Async iteration
[Symbol.asyncIterator](): AsyncIterator<Node>
}
class Pattern {
constructor(pattern: object)
}
class Variable {
constructor(name: string)
}
DRIFT Search API¶
DRIFT (Dynamic Retrieval & Drift Detection) provides intent-based search modes optimized for GraphRAG workflows. The API includes drift detection for corpus monitoring and three search modes: BROAD (community-level), SPECIFIC (entity-level), and COMPLEX (dual-level).
detectDrift(documents)¶
Detect drift in a corpus of documents by comparing hashes. This native implementation provides < 100ms performance for 10k documents.
const documents = [
{ id: 'doc1', hash: 'abc123' },
{ id: 'doc2', hash: 'def456' }
];
const result = await conn.detectDrift(documents);
console.log(result);
// {
// drift_ratio: 0.0,
// new_count: 0,
// modified_count: 0,
// unchanged_count: 2,
// new_ids: [],
// modified_ids: []
// }
Parameters:
- documents - Array of { id: string, hash: string } entries
Returns:
- drift_ratio - Ratio of changed documents (0.0 to 1.0)
- new_count - Number of new documents
- modified_count - Number of modified documents
- unchanged_count - Number of unchanged documents
- new_ids - IDs of new documents
- modified_ids - IDs of modified documents
driftSearch(queryVector, options)¶
Perform DRIFT search with intent-based routing.
const queryVector = new Array(384).fill(0.1);
queryVector[0] = 0.5;
const result = await conn.driftSearch(queryVector, {
intent: 'COMPLEX', // 'BROAD' | 'SPECIFIC' | 'COMPLEX'
local_k: 10,
global_k: 10,
community_level: 0,
ef: 50
});
console.log(`Intent: ${result.intent}`);
console.log(`Found ${result.local_results.length} entities`);
console.log(`Found ${result.global_results.length} communities`);
console.log(`Execution time: ${result.metadata.execution_time_ms}ms`);
Parameters:
- queryVector - Query embedding vector (Arrayoptions - Search options:
- intent - Search mode: 'BROAD', 'SPECIFIC', or 'COMPLEX'
- local_k - Number of local results (entities)
- global_k - Number of global results (communities)
- community_level - Community hierarchy level (default: 0)
- ef - HNSW ef parameter (default: 50)
Returns:
- intent - Intent mode used
- local_results - Array of entity-level results
- global_results - Array of community-level results
- metadata - Search metadata including execution time
Intent Modes:
-
'BROAD'- Community-level search for global context -
'SPECIFIC'- Entity-level search for precise answers -
'COMPLEX'- Dual-level retrieval combining both
searchCommunities(queryVector, level, k, ef)¶
Search communities at a specific hierarchy level.
const communities = await conn.searchCommunities(
queryVector,
0, // level 0 (leaf communities)
10, // k (number of results)
50 // ef (HNSW parameter)
);
for (const c of communities) {
console.log(`Community ${c.node_id} at level ${c.level}`);
console.log(`Distance: ${c.distance}`);
}
Parameters:
- queryVector - Query embedding vector
- level - Community hierarchy level (0 = leaf communities)
- k - Number of results to return
- ef - HNSW ef parameter
Returns:
- Array of community results with node_id, distance, level, and node properties
See Also¶
- Choosing Your Query Interface - Decision guide for Cypher vs JavaScript API vs Navigator
- JavaScript Native Bindings - Database, Connection, and QueryResult reference
- Cypher Reference - Query language syntax