Neo4j handbook for Nodejs and Python

A lightning‑fast handbook of the only commands you need to stand up, populate, and query a Neo4j graph from JavaScript (Node.js) or Python. Copy, paste, ship.


Basic Concepts

  • Node – an entity/record; can hold multiple labels (e.g., :Person, :Customer).
  • Relationship – a directed, typed edge between two nodes (e.g., [:KNOWS]); stores its own properties.
  • Property – key–value data on nodes or relationships (name, age, since).
  • Path – an ordered chain of nodes & relationships; assign it with p = (a)-[:REL]->(b).
  • Cypher – the query language; core verbs: MATCH, CREATE, MERGE, SET/REMOVE, DELETE, RETURN/WITH, WHERE.
  • Indexes – speed up look‑ups on frequently filtered properties (CREATE INDEX ...).
  • Constraints – enforce integrity (e.g., uniqueness: ... REQUIRE email IS UNIQUE).
  • Transaction – ACID wrapper around one or more operations (session.write_transaction(...)).
  • APOC / GDS – plugin libraries providing utilities (APOC) and graph algorithms (GDS) for power users.

1 Setup & Connection Setup & Connection

Install Drivers

  • Node.js npm i neo4j-driver
  • Python pip install neo4j

Connect (Bolt URI)

// Node.js
const neo4j = require('neo4j-driver');
const driver = neo4j.driver('neo4j://localhost:7687',
  neo4j.auth.basic('neo4j', 'password'));
const session = driver.session({ database: 'neo4j' });
# Python
from neo4j import GraphDatabase

driver = GraphDatabase.driver('neo4j://localhost:7687',
                              auth=("neo4j", "password"))
with driver.session() as session:
    ...

Tip Use neo4j+s:// for AuraDB or any TLS‑encrypted endpoint.

Close when done:

await session.close();
await driver.close();
session.close()
driver.close()

2 Create Nodes (Labels ≈ Tables)

await session.run(
  'CREATE (p:Person {name:$name, age:$age})',
  { name: 'Alice', age: 30 }
);
session.run(
  "CREATE (p:Person {name:$name, age:$age})",
  {"name": "Alice", "age": 30}
)

Use parameters ($name)—never string‑concatenate user input.


3 Create Relationships

await session.run(
  'MATCH (a:Person {name:$from}), (b:Person {name:$to})\n'
+ 'CREATE (a)-[:KNOWS {since:$y}]->(b)',
  { from: 'Alice', to: 'Bob', y: 2020 }
);
session.run(
  "MATCH (a:Person {name:$from}), (b:Person {name:$to}) "
  "CREATE (a)-[:KNOWS {since:$y}]->(b)",
  {"from": "Alice", "to": "Bob", "y": 2020}
)

4 Read / Match Patterns

Basic lookup

MATCH (p:Person {name:$name}) RETURN p;

Traversal (friends of friends)

MATCH (p:Person {name:$name})-[:KNOWS]->()-[:KNOWS]->(fof)
RETURN DISTINCT fof.name;

Retrieve in code:

const res = await session.run(query,{name:'Alice'});
res.records.forEach(r=>console.log(r.get(0)));
for record in session.run(query, name="Alice"):
    print(record[0])

5 Filtering, Ordering, Pagination

MATCH (p:Person)
WHERE p.age > $minAge
RETURN p.name, p.age
ORDER BY p.name
SKIP $skip LIMIT $limit;

Params {minAge:30, skip:10, limit:5}


6 Aggregations

MATCH (p:Person)-[:KNOWS]->(f:Person)
RETURN p.name, count(f) AS friends
ORDER BY friends DESC;

Collect list:

MATCH (p)-[:KNOWS]->(f)
RETURN p.name, collect(f.name) AS friendList;

7 Shortest Path

MATCH p = shortestPath((a:Person {name:$a})-[:KNOWS*..5]-(b:Person {name:$b}))
RETURN nodes(p) AS hops;

8 Schema: Indexes & Constraints

// Uniqueness
CREATE CONSTRAINT unique_email IF NOT EXISTS
FOR (u:User) REQUIRE u.email IS UNIQUE;

// Simple index
CREATE INDEX person_name IF NOT EXISTS FOR (p:Person) ON (p.name);

List:

SHOW CONSTRAINTS;   SHOW INDEXES;

9 Batch Inserts with UNWIND

const people=[{name:'Dan',age:33},{name:'Eve',age:28}];
await session.run(
  'UNWIND $rows AS row CREATE (p:Person) SET p = row',
  {rows: people}
);
people=[{"name":"Dan","age":33},{"name":"Eve","age":28}]
session.run(
  "UNWIND $rows AS row CREATE (p:Person) SET p = row",
  {"rows": people}
)

10 Transactions (Python shown)

def add_friend(tx, a, b):
    tx.run("MATCH (x:Person {name:$a}), (y:Person {name:$b}) "
           "MERGE (x)-[:KNOWS]->(y)", a=a, b=b)
with driver.session() as s:
    s.write_transaction(add_friend, "Alice", "Carol")

Node.js equivalent: await session.executeWrite(tx=>tx.run(...))


11 Profile & Tune

  • EXPLAIN <query> → show plan without running.
  • PROFILE <query> → run & return db‑hits, rows, time.
  • Look for NodeByLabelScan (slow). Add indexes until you see NodeIndexSeek / NodeIndexScan.

12 Close & Cleanup

Always:

await session.close();
await driver.close();
session.close()
driver.close()

Mini‑Glossary

Term Meaning
Node Entity / record (row)
Label Node tag (table name)
Relationship Typed, directed edge
Property Key–value on node/rel
Path Ordered chain of nodes & relationships
Cypher Query language

One‑Minute Warm‑up Script (Node.js)

import neo4j from 'neo4j-driver';
const d = neo4j.driver('neo4j://localhost', neo4j.auth.basic('neo4j','pass'));
const s = d.session();
await s.run("CREATE (:Person {name:'Neo'})");
const res = await s.run("MATCH (n:Person) RETURN n.name AS name");
console.log(res.records[0].get('name')); // -> Neo
await s.close();
await d.close();

Print this page, stick it on your monitor, and graph fearlessly. 🚀

comment

Comments

arrow_back

Previous

About Life Hacks

Next

Leveling Up: A Journey Through the Fundamentals of Generative AI - Season 1 Recap
arrow_forward