The official Neo4j driver for JavaScript applications, enabling connection to and interaction with Neo4j graph databases.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Neo4j graph data types including nodes, relationships, and paths with comprehensive type checking utilities.
Represents a node in the Neo4j graph with identity, labels, and properties.
interface Node {
/** Unique node identity within the database */
identity: Integer;
/** Array of labels assigned to the node */
labels: string[];
/** Key-value properties stored on the node */
properties: Record<string, any>;
/** Convert node to string representation */
toString(): string;
}
/**
* Check if an object is a Neo4j Node
* @param obj - Object to check
* @returns true if object is a Node instance
*/
function isNode(obj: any): obj is Node;Usage Examples:
import { driver, auth, isNode } from "neo4j-driver";
const session = neo4jDriver.session();
try {
const result = await session.run(`
CREATE (p:Person:User {
name: $name,
age: $age,
email: $email,
createdAt: datetime()
})
RETURN p
`, {
name: "Alice Johnson",
age: 30,
email: "alice@example.com"
});
const nodeRecord = result.records[0];
const person = nodeRecord.get("p");
if (isNode(person)) {
console.log(`Node ID: ${person.identity}`);
console.log(`Labels: ${person.labels.join(", ")}`); // "Person, User"
console.log(`Name: ${person.properties.name}`); // "Alice Johnson"
console.log(`Age: ${person.properties.age}`); // 30
console.log(`Email: ${person.properties.email}`); // "alice@example.com"
// Access all properties
Object.entries(person.properties).forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});
}
} finally {
await session.close();
}Represents a relationship between nodes with type, properties, and endpoint references.
interface Relationship {
/** Unique relationship identity within the database */
identity: Integer;
/** Identity of the start node */
start: Integer;
/** Identity of the end node */
end: Integer;
/** Relationship type name */
type: string;
/** Key-value properties stored on the relationship */
properties: Record<string, any>;
/** Convert relationship to string representation */
toString(): string;
}
/**
* Check if an object is a Neo4j Relationship
* @param obj - Object to check
* @returns true if object is a Relationship instance
*/
function isRelationship(obj: any): obj is Relationship;Usage Examples:
const result = await session.run(`
MATCH (p1:Person {name: $name1}), (p2:Person {name: $name2})
CREATE (p1)-[r:KNOWS {
since: date(),
strength: $strength,
context: $context
}]->(p2)
RETURN r, p1, p2
`, {
name1: "Alice",
name2: "Bob",
strength: 0.8,
context: "work"
});
const record = result.records[0];
const relationship = record.get("r");
const startNode = record.get("p1");
const endNode = record.get("p2");
if (isRelationship(relationship)) {
console.log(`Relationship ID: ${relationship.identity}`);
console.log(`Type: ${relationship.type}`); // "KNOWS"
console.log(`From: ${relationship.start} To: ${relationship.end}`);
console.log(`Since: ${relationship.properties.since}`);
console.log(`Strength: ${relationship.properties.strength}`); // 0.8
console.log(`Context: ${relationship.properties.context}`); // "work"
// Verify endpoints match nodes
console.log(`Start matches: ${relationship.start.equals(startNode.identity)}`);
console.log(`End matches: ${relationship.end.equals(endNode.identity)}`);
}Represents relationship data without specific start/end node references.
interface UnboundRelationship {
/** Unique relationship identity within the database */
identity: Integer;
/** Relationship type name */
type: string;
/** Key-value properties stored on the relationship */
properties: Record<string, any>;
/** Convert unbound relationship to string representation */
toString(): string;
}
/**
* Check if an object is a Neo4j UnboundRelationship
* @param obj - Object to check
* @returns true if object is an UnboundRelationship instance
*/
function isUnboundRelationship(obj: any): obj is UnboundRelationship;Usage Examples:
// Unbound relationships typically appear in path segments
const result = await session.run(`
MATCH path = (start:Person {name: $name})-[*1..3]-(end:Person)
RETURN path
`, { name: "Alice" });
result.records.forEach(record => {
const path = record.get("path");
path.segments.forEach(segment => {
if (isUnboundRelationship(segment.relationship)) {
console.log(`Unbound relationship: ${segment.relationship.type}`);
console.log(`Properties:`, segment.relationship.properties);
}
});
});Represents a path through the graph containing nodes and relationships.
interface Path {
/** Starting node of the path */
start: Node;
/** Ending node of the path */
end: Node;
/** Number of relationships in the path */
length: number;
/** Array of path segments (node-relationship pairs) */
segments: PathSegment[];
/** Array of all nodes in the path */
nodes: Node[];
/** Array of all relationships in the path */
relationships: Relationship[];
/** Convert path to string representation */
toString(): string;
}
/**
* Check if an object is a Neo4j Path
* @param obj - Object to check
* @returns true if object is a Path instance
*/
function isPath(obj: any): obj is Path;Usage Examples:
const result = await session.run(`
MATCH path = (start:Person {name: $name})-[:KNOWS*1..3]-(end:Person)
WHERE start <> end
RETURN path
LIMIT 5
`, { name: "Alice" });
result.records.forEach(record => {
const path = record.get("path");
if (isPath(path)) {
console.log(`Path from ${path.start.properties.name} to ${path.end.properties.name}`);
console.log(`Path length: ${path.length} relationships`);
// Examine each segment
path.segments.forEach((segment, index) => {
console.log(`Segment ${index + 1}:`);
console.log(` Node: ${segment.start.properties.name}`);
console.log(` Relationship: ${segment.relationship.type}`);
console.log(` End: ${segment.end.properties.name}`);
});
// Alternative: iterate through nodes and relationships
console.log("Path nodes:", path.nodes.map(n => n.properties.name).join(" -> "));
console.log("Relationship types:", path.relationships.map(r => r.type).join(", "));
}
});Represents a single segment of a path containing a relationship and its connected nodes.
interface PathSegment {
/** Starting node of the segment */
start: Node;
/** Relationship in the segment */
relationship: Relationship;
/** Ending node of the segment */
end: Node;
/** Convert path segment to string representation */
toString(): string;
}
/**
* Check if an object is a Neo4j PathSegment
* @param obj - Object to check
* @returns true if object is a PathSegment instance
*/
function isPathSegment(obj: any): obj is PathSegment;Usage Examples:
const result = await session.run(`
MATCH path = (a:Person)-[r:WORKS_FOR]->(c:Company)-[r2:LOCATED_IN]->(city:City)
RETURN path
LIMIT 1
`);
const path = result.records[0].get("path");
if (isPath(path)) {
path.segments.forEach((segment, index) => {
if (isPathSegment(segment)) {
console.log(`Segment ${index + 1}:`);
console.log(` Start: ${segment.start.labels.join(":")} ${segment.start.properties.name}`);
console.log(` Relationship: ${segment.relationship.type}`);
console.log(` End: ${segment.end.labels.join(":")} ${segment.end.properties.name}`);
// Access relationship properties
if (Object.keys(segment.relationship.properties).length > 0) {
console.log(` Relationship properties:`, segment.relationship.properties);
}
}
});
}Utility object containing all graph type checking functions.
declare const graph: {
/** Check if object is a Node */
isNode: typeof isNode;
/** Check if object is a Relationship */
isRelationship: typeof isRelationship;
/** Check if object is an UnboundRelationship */
isUnboundRelationship: typeof isUnboundRelationship;
/** Check if object is a Path */
isPath: typeof isPath;
/** Check if object is a PathSegment */
isPathSegment: typeof isPathSegment;
};Usage Examples:
import { graph } from "neo4j-driver";
const result = await session.run(`
MATCH path = (p:Person)-[r:KNOWS]->(friend:Person)
RETURN p, r, friend, path
LIMIT 1
`);
const record = result.records[0];
// Type checking with utility object
if (graph.isNode(record.get("p"))) {
console.log("Found a person node");
}
if (graph.isRelationship(record.get("r"))) {
console.log("Found a knows relationship");
}
if (graph.isPath(record.get("path"))) {
console.log("Found a friendship path");
}
// Generic type checking function
function analyzeGraphObject(obj: any, name: string) {
if (graph.isNode(obj)) {
console.log(`${name} is a Node with labels: ${obj.labels.join(", ")}`);
} else if (graph.isRelationship(obj)) {
console.log(`${name} is a Relationship of type: ${obj.type}`);
} else if (graph.isPath(obj)) {
console.log(`${name} is a Path with ${obj.length} relationships`);
} else if (graph.isPathSegment(obj)) {
console.log(`${name} is a PathSegment`);
} else if (graph.isUnboundRelationship(obj)) {
console.log(`${name} is an UnboundRelationship of type: ${obj.type}`);
} else {
console.log(`${name} is not a graph type`);
}
}
// Analyze all returned values
record.keys.forEach(key => {
analyzeGraphObject(record.get(key), key);
});Usage Examples:
// Complex path analysis
const result = await session.run(`
MATCH path = (person:Person {name: $name})-[:LIVES_IN]->
(city:City)-[:LOCATED_IN]->
(country:Country)
RETURN path, person, city, country
`, { name: "Alice" });
result.records.forEach(record => {
const path = record.get("path");
if (isPath(path)) {
// Analyze path structure
console.log(`Path: ${path.start.properties.name} lives in ${path.end.properties.name}`);
console.log(`Path contains ${path.nodes.length} nodes and ${path.relationships.length} relationships`);
// Extract specific information
const person = path.nodes.find(n => n.labels.includes("Person"));
const city = path.nodes.find(n => n.labels.includes("City"));
const country = path.nodes.find(n => n.labels.includes("Country"));
if (person && city && country) {
console.log(`${person.properties.name} lives in ${city.properties.name}, ${country.properties.name}`);
}
// Analyze relationships
path.relationships.forEach(rel => {
if (rel.type === "LIVES_IN") {
console.log(`Living since: ${rel.properties.since || "unknown"}`);
} else if (rel.type === "LOCATED_IN") {
console.log(`City is in country: ${rel.properties.established || "unknown"}`);
}
});
}
});