Skip to content

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

new CongraphDBAPI(dbOrConnection: Database | Connection)

Creates a new CongraphDBAPI instance. Accepts either a Database or Connection object.

const api = new CongraphDBAPI(db);
// or
const api = new CongraphDBAPI(connection);

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.

const node = await api.getNode('node-id-here');
// Returns the node object or null if not found

getNodesByLabel(label)

Get all nodes with a specific label.

const users = await api.getNodesByLabel('User');
// Returns: Array of node objects

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.

const edge = await api.getEdge('edge-id-here');

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.

const updated = await api.updateEdge('edge-id', {
  since: 2021,
  strength: 5
});

deleteEdge(id)

Delete an edge.

await api.deleteEdge('edge-id');

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
});

Create a Navigator for fluent graph traversal.

const navigator = api.nav('node-id');

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.

await api.schema.dropTable('OldTable');

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.

await api.close();

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.

await conn.resetOccStatistics();

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.

await conn.clearVersionCache();

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.

await store.addBulk('Documents', largeArray, { 
  chunkSize: 1000,
  deferIndex: true 
});

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.

const batchResults = await store.searchBatch('Documents', [vec1, vec2]);

Utilities

checkpoint()

Force persist pending changes to disk (WAL flush).

await store.checkpoint();

close()

Safely close the store and flush all data.

await store.close();

See also: OCC Guide for complete OCC documentation.


Fluent graph traversal API (LevelGraph-compatible).

Creating a Navigator

const nav = api.nav('starting-node-id');

Traversal Methods

out(relType)

Traverse outgoing relationships.

const friends = await api.nav(alice._id)
  .out('KNOWS')
  .values();

in(relType)

Traverse incoming relationships.

const followers = await api.nav(alice._id)
  .in('KNOWS')
  .values();

both(relType)

Traverse relationships in both directions.

const connections = await api.nav(alice._id)
  .both('KNOWS')
  .values();

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.

const firstFive = await api.nav(alice._id)
  .out('KNOWS')
  .limit(5)
  .values();

Path Finding

to(targetId)

Find the shortest path to a target node.

const path = await api.nav(alice._id)
  .out('KNOWS')
  .to(bob._id)
  .values();

Getting Results

values()

Get matching nodes as an array.

const nodes = await api.nav(alice._id)
  .out('KNOWS')
  .values();

paths()

Get full paths (including intermediate nodes and edges).

const paths = await api.nav(alice._id)
  .out('KNOWS')
  .out('KNOWS')
  .paths();

count()

Count matching nodes.

const count = await api.nav(alice._id)
  .out('KNOWS')
  .count();

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:

for await (const friend of api.nav(alice._id).out('KNOWS')) {
  console.log(friend.name);
}

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

const pattern = new Pattern({
  subject: alice._id,
  predicate: 'KNOWS',
  object: api.v('friend')
});

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

const friendVar = api.v('friend');
const personVar = api.v('person');

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 (Array) - options - 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

    const result = await conn.driftSearch(queryVector, {
      intent: 'BROAD',
      global_k: 10,
      community_level: 0
    });
    

  • 'SPECIFIC' - Entity-level search for precise answers

    const result = await conn.driftSearch(queryVector, {
      intent: 'SPECIFIC',
      local_k: 10
    });
    

  • 'COMPLEX' - Dual-level retrieval combining both

    const result = await conn.driftSearch(queryVector, {
      intent: 'COMPLEX',
      local_k: 10,
      global_k: 10
    });
    

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