GraphDB-Neo4J Cypher Query handbook

Ritresh Girdhar
6 min readFeb 25, 2025

--

This handbook serves as a comprehensive reference for Cypher queries in Neo4j, covering CRUD operations, relationships, constraints, querying techniques, and advanced query optimizations. Whether a beginner or an experienced developer, this guide will help you efficiently manage data in Neo4j.

Creating Nodes

Create Node without a label

create ()

Note: Nodes without labels are rarely useful in real-world applications.

Create a Node with a Label

create (st:Student),(sub:Subject) return st, sub

Labeling nodes help categorize data effectively and improve query performance.

Retrieve All Nodes

match (x) return x;

Retrieve Nodes by Label

match (st: Student) return st;
match (sub: Subject) return sub;

Create Node with Properties

create (st:Student{name: 'abc'}) return st
create (st:Student{name: 'def'}) return st

Retrieve Nodes by Property

match (st:Student) where st.name='abc' return st

Retrieve Nodes by ID
Note — (Neo4J creates an ID for each node)

match (st:Student) where ID(st)=10 return st

Creating Relationships

Create a Node and Relationship

create (st:Student{name: 'abc'})-[:IS_LEARNING]->(sub:Subject{sub_name:"Math"}) 
return st, sub

Create a Relationship with Properties

create (st:Student{name: 'def'})-[:IS_LEARNING{marks: 90}]->(sub:Subject{
sub_name:"Math"}) return st, sub

Create Multiple Relationships

create (dep: Department{dep_name: "Computer Science"}) 
<-[:BELONGS_TO]-(st:Student{name: 'def'})-[:IS_LEARNING{marks: 90}]->
(sub:Subject{sub_name:"Math"}) return st, sub, dep

Retrieving Data

Retrieve All Students with Any Relationship

match (st:Student)-[:IS_LEARNING]->(node)
return st,node

Retrieve Students Learning ‘Math’

match (st:Student)-[:IS_LEARNING]->(sub:Subject)
where sub.sub_name="Math"
return st;

Retrieve Students with Multiple Relationships

match (st:Student)-[:IS_LEARNING | :BELONGS_TO ]->(node)
return st,node

Retrieve all Students with relationships (with neo4j Browser setting off)

match (st:Student)-[rel:IS_LEARNING | BELONGS_TO ]->(node)
return st,node,rel

Updating Relationships

Update Relationship Properties

match (st:Student)-[rel:IS_LEARNING]->(sub:Subject{sub_name:'Mysql'})
where ID(st)=13
set rel.progress="50%", rel.marks=80
return st,sub ,rel

Delete Relationship Properties

match (st:Student)-[rel:IS_LEARNING]->(sub:Subject{sub_name:'Mysql'})
where ID(st)=13
remove rel.progress
return st,sub ,rel

Delete relationship

match (st:Student)-[rel:IS_LEARNING]->(sub:Subject{sub_name:'Mysql'})
where ID(st)=13
delete rel
return st,sub

Check relationship after deletion

match (st:Student)-[rel]->(sub)
where ID(st)=13
return st,sub ,rel

Update Relationship Type

Change :IS_LEARNING to :WAS_LEARNING

match (st:Student)-[oldRel:IS_LEARNING]->(sub:Subject{sub_name:'PHP'})
where ID(st)=13
merge (st)-[newRel:WAS_LEARNING]->(sub)
set newRel= oldRel
delete oldRel
return sub,st,newRel
match (st:Student)-[rel]->(sub)
where ID(st)=13
return sub,st,rel

Deleting Nodes and Relationships

Delete a Node with Relationships

match (st:Student{name: 'Martin'})-[rel]->(sub)
where ID(st)=10
delete st

It will throw an exception, as deleting a node that has a relationship, will fail. For this, we also require to del the relationship.


match (st:Student{name: 'Martin'})-[anyRel]->(sub)
where ID(st)=10
delete st,anyRel
match (st:Student{name: 'Martin'})-[anyRel]->(sub)
where ID(st)=10
return st,anyRel,sub

Delete All Nodes Without Relationships

match (node) delete node

Delete All Nodes and Relationships

match (node)-[rel]-(node1) delete node,rel,node1

Delete node with and without relationship — in a single shot

match (n) return n

There are two options:

  • Optional Match
match (anyNode)-[anyRel]-(node1)
optional match (node)
delete anyNode,anyRel,node
  • Detach Delete
match (node) detach delete node

Constraints and Indexes

  1. Unique Constraints
  2. Property Existence Constraints
  3. Node Key Constraints
  4. Show Constraints
  5. Drop Constraints

Unique Constraints on node property only

create constraint sub_name_unique For (sub:Subject) 
Require sub.sub_name is unique

For older versions of Neo4J —

create constraint sub_name_unique on (sub:Subject) 
assert(sub.sub_name) is unique

To test the above constraint, run the query below twice.

create (sub:Subject{sub_name:'Neo4j'})

Let's try to create a subject without property sub_name, above constraint will not work for null

create (sub: Subject)

Property Existence Constraints

create constraint st_name_exist for (st:Student) 
Require st.name IS NOT NULL;

To test the above constraint, run the command below.

create (st:Student)

It failed because of the constraint, let's run the same query with the required property “name”

create (st:Student{name:'Rahul'})

Query All Students

match(x:Student) return x

Relationship Constraint (Mandatory Field in Relationship)

create constraint learning_marks_exist FOR ()-[rel:IS_LEARNING]-() 
Require rel.marks IS NOT NULL

To test above constraint — run below command

match (st:Student{name:'Rahul'}),(sub:Subject{sub_name:'Neo4j'})
merge (st)-[rel:IS_LEARNING]->(sub)
return st,sub,rel

The above command failed because of missing required relationship property.

match (st:Student{name:'Rahul'}),(sub:Subject{sub_name:'Neo4j'})
merge (st)-[rel:IS_LEARNING{marks:80}]->(sub)
return st,sub,rel

Node Key Constraint (Unique + Not Null)

create constraint student_id_node_key For (st:Student) 
Require st.student_id is node key

Multiple properties constraints (like a composite key)

create constraint student_id_birth_year_node_key For (st:Student) 
Require (st.student_id , st.birth_year) is node key

List all the constraints

show constraints

Drop the constraint

drop constraint st_name_exist

List all constraints — To check above one deleted

Query Optimization Techniques

String Matching

Property Contains String

match (st:Student)-[rel]->(sub) where st.name CONTAINS 'tin' 
return st,rel,sub

Case-Insensitive Matching

match (st:Student)-[rel]->(sub) 
where toUpper(st.name) CONTAINS 'TIN'
return st,rel,sub

Starts With

match (st:Student)-[rel]->(sub) 
where st.name starts with 'R'
return st,rel,sub
match (st:Student)-[rel]->(sub) 
where toLower(st.name) starts with 'r'
return st,rel,sub

Ends with

match (st:Student) where st.name ends with ‘esh’ return st

Aggregations

Counting

match (st:Student)-[rel]-(sub) return st,rel,sub
match (st:Student)-[rel]-(sub) return count(st.country)
match (st:Student) return st.country as country, count(st.country) as `Number of Students`

Summing Relationship Properties

match (st:Student)-[rel:IS_LEARNING]-(sub) 
return st.name as Name, sum(rel.marks) as Marks

Distinct

match (st:Student)
with distinct st.name as Name
return Name

Pagination

match(st:Student) return st skip 0 limit 2
match(st:Student) return st skip 2 limit 4

Sorting

match(st:Student) return st order by st.name asc

Conclusion

This handbook provides a solid foundation for working with Neo4j’s Cypher query language. It covers fundamental concepts, query optimizations, and best practices to help you efficiently model and retrieve data in Neo4j.

--

--

Ritresh Girdhar
Ritresh Girdhar

Written by Ritresh Girdhar

Father || Coder || Engineer || Learner || Reader || Writer || Silent Observer

No responses yet