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