Learn basic Cypher queries to create, read, update, and delete graph data.
- NornicDB installed and running (see Installation)
- Connected to database (HTTP or Bolt)
- Creating nodes and relationships
- Querying graph data
- Updating properties
- Deleting data
- Basic graph patterns
Let's create a person node:
CREATE (alice:Person {
name: "Alice Johnson",
age: 30,
email: "alice@example.com"
})
RETURN aliceWhat this does:
CREATE- Creates a new node(alice:Person ...)- Variable namealice, labelPerson{name: ..., age: ...}- Properties (see Property Data Types for all supported types)RETURN alice- Returns the created node
CREATE
(bob:Person {name: "Bob Smith", age: 35}),
(carol:Person {name: "Carol White", age: 28}),
(company:Company {name: "TechCorp", founded: 2010})
RETURN bob, carol, companyConnect Alice to the company:
MATCH
(alice:Person {name: "Alice Johnson"}),
(company:Company {name: "TechCorp"})
CREATE (alice)-[r:WORKS_AT {since: 2020, role: "Engineer"}]->(company)
RETURN alice, r, companyRelationship syntax:
(alice)-[r:WORKS_AT {...}]->(company)- Directed relationshipr:WORKS_AT- Relationship type{since: 2020, role: "Engineer"}- Relationship properties
MATCH (p:Person)
RETURN p.name, p.age
ORDER BY p.age DESCMATCH (p:Person)-[r:WORKS_AT]->(c:Company)
RETURN p.name, r.role, c.nameMATCH (p:Person)
WHERE p.age > 30
RETURN p.name, p.age// Find people who work at the same company
MATCH (p1:Person)-[:WORKS_AT]->(c:Company)<-[:WORKS_AT]-(p2:Person)
WHERE p1.name < p2.name // Avoid duplicates
RETURN p1.name, p2.name, c.nameMATCH (alice:Person {name: "Alice Johnson"})
SET alice.age = 31, alice.city = "San Francisco"
RETURN aliceMATCH (alice:Person {name: "Alice Johnson"})
SET alice:Employee:Manager
RETURN labels(alice)MATCH (alice:Person {name: "Alice Johnson"})
REMOVE alice.email
RETURN aliceMATCH (bob:Person {name: "Bob Smith"})
DETACH DELETE bobNote: DETACH DELETE removes the node and all its relationships.
MATCH (alice:Person)-[r:WORKS_AT]->()
DELETE rMATCH (n)
DETACH DELETE nMERGE (alice:Person {name: "Alice Johnson"})
ON CREATE SET alice.created = timestamp()
ON MATCH SET alice.accessed = timestamp()
RETURN aliceMATCH (p:Person)
RETURN count(p) as totalPeopleMATCH (p:Person)
RETURN
count(p) as total,
avg(p.age) as averageAge,
min(p.age) as youngest,
max(p.age) as oldestMATCH (p:Person)
RETURN collect(p.name) as allNamesLet's build a small social network:
// Create people
CREATE
(alice:Person {name: "Alice", age: 30}),
(bob:Person {name: "Bob", age: 35}),
(carol:Person {name: "Carol", age: 28}),
(dave:Person {name: "Dave", age: 32})
// Create friendships
CREATE
(alice)-[:FRIENDS_WITH {since: 2020}]->(bob),
(alice)-[:FRIENDS_WITH {since: 2019}]->(carol),
(bob)-[:FRIENDS_WITH {since: 2021}]->(dave),
(carol)-[:FRIENDS_WITH {since: 2020}]->(dave)
RETURN *MATCH (alice:Person {name: "Alice"})-[:FRIENDS_WITH*2]-(fof:Person)
WHERE alice <> fof
RETURN DISTINCT fof.name as friendOfFriendMATCH path = shortestPath(
(alice:Person {name: "Alice"})-[:FRIENDS_WITH*]-(dave:Person {name: "Dave"})
)
RETURN pathCREATE (doc:Document {
title: "README",
metadata: {
author: "Alice",
version: "1.0",
tags: ["documentation", "guide"]
}
})
RETURN docCREATE (person:Person {
name: "Alice",
skills: ["Python", "Go", "JavaScript"],
languages: ["English", "Spanish"]
})
RETURN personMATCH (doc:Document)
RETURN doc.metadata.author, doc.metadata.tags// Instead of:
MATCH (p:Person {name: "Alice"})
// Use parameters:
MATCH (p:Person {name: $name})CREATE INDEX person_name FOR (p:Person) ON (p.name)EXPLAIN MATCH (p:Person) WHERE p.age > 30 RETURN pPROFILE MATCH (p:Person)-[:WORKS_AT]->(c:Company) RETURN p, cMATCH (p:Person)
RETURN p
LIMIT 10MATCH (p:Person)
RETURN
toLower(p.name) as lowercase,
toUpper(p.name) as uppercase,
substring(p.name, 0, 3) as first3charsRETURN
abs(-5) as absolute,
round(3.14159, 2) as rounded,
sqrt(16) as squareRootRETURN
size([1,2,3,4,5]) as listSize,
head([1,2,3]) as firstElement,
tail([1,2,3]) as restOfListNow that you know the basics:
- Vector Search Guide - Semantic search
- Complete Examples - Full applications
- Cypher Functions Reference - All functions
- Advanced Topics - K-Means clustering, embeddings, custom functions
- Make sure you created the node first
- Check spelling of labels and properties
- Use
DETACH DELETEinstead ofDELETE
- Create indexes on frequently queried properties
- Use
EXPLAINto analyze query plan - Limit result sets with
LIMIT
Need more examples? → Complete Examples
Ready for advanced features? → User Guides