Querying the graph¶
MATCH¶
The MATCH
keyword in Cypher is what searches for an existing node, relationship, label, property, or pattern in the database.
If you are familiar with SQL, MATCH works pretty much like SELECT in SQL.
WHERE¶
Not a clause in its own right, but adds constraints to a pattern, or filters the intermediate results.
RETURN¶
The RETURN
keyword in Cypher specifies what values or results you might want to return from a Cypher query.
You can tell Cypher to return nodes, relationships, node and relationship properties, or patterns in your query results.
RETURN is not required when doing write procedures, but is needed for reads.
Just like with SQL, you can rename return results by using the AS
keyword and aliasing the property with a cleaner name.
MATCH (p:Person)
RETURN p.name AS name
Let’s start creating a very simple network :
CREATE (a:Person {name: 'Messi'})
CREATE (b:Person {name: 'Neymar'})
CREATE (c:Person {name: 'DeBruyne'})
CREATE (d:Person {name: 'Lukaku'})
CREATE (e:Person {name: 'Vertongen'})
CREATE (a)-[:KNOWS]->(b)-[:KNOWS]->(d)
CREATE (a)-[:KNOWS]->(c)
CREATE (c)-[:KNOWS]->(d)
CREATE (c)-[:KNOWS]->(e)
which results in :

Four elements can be returned by the RETURN clause:
Nodes
MATCH (n {name: 'Lukaku'}) RETURN n
Relationships
⚒ Find the outgoing relationships from the player with the name “Messi”
MATCH (n {name: 'Messi'})-[r:KNOWS]->(c) RETURN r
Properties
⚒ Return all the properties from all the nodes of type person
MATCH (n:Person) RETURN n.name
All elements
In that case use “*” in the return statement.
WITH¶
The WITH clause allows query parts to be chained together, piping the results from one to be used as starting points or criteria in the next.
⚒ A list of the names of people in reverse order, limited to 3, is returned in a list.
MATCH (n)
WITH n
ORDER BY n.name DESC
LIMIT 3
RETURN collect(n.name)
results in: [“Vertongen”, “Neymar”, “Messi”]
You can match paths, limit to a certain number, and then match again using those paths as a base, as well as any number of similar limited searches.
⚒ Starting at ‘Messi’, find all matching nodes, order by name descending and get the top result, then find all the nodes connected to that top result, and return their names.
MATCH (n {name:'Messi'})--(m)
WITH m
ORDER BY m.name DESC
LIMIT 1
MATCH (m)--(o)
RETURN o.name
⚒ Find the name of the player connected to ‘Vertongen’ with the at least more than one outgoing relationship.
MATCH (player {name: 'Vertongen'})--(otherPerson)-->()
WITH otherPerson, count(*) AS foaf
WHERE foaf >0
RETURN otherPerson.name
This will return [“DeBruyne”]
UNWIND¶
With UNWIND, you can transform any list back into individual rows. These lists can be parameters that were passed in, previously collected result or other list expressions.
WITH
[1, 2] AS a,
[3, 4] AS b
UNWIND (a + b) AS x
RETURN x
The two lists — a and b — are concatenated to form a new list, which is then operated upon by UNWIND.
SKIP¶
SKIP defines from which row to start including the rows in the output.
MATCH (n)
RETURN n.name
ORDER BY n.name
SKIP 2
Returns : “Messi”,”Neymar”,”Vertongen”
LIMIT¶
To return a limited subset of the rows, use this syntax:
MATCH (n)
RETURN n.name
ORDER BY n.name
LIMIT 3
REMOVE¶
Neo4j doesn’t allow storing null in properties. Instead, if no value exists, the property is just not there. So, REMOVE is used to remove a property value from a node or a relationship.
MATCH (a {name: 'Andy'})
REMOVE a.age
RETURN a.name, a.age
It is also possible to remove a label from a node using the REMOVE clause. The code below removes all the GoalKeeper labels.
MATCH (n)
REMOVE n:GoalKeeper
RETURN n.name, labels(n)
FOREACH¶
To study the concept better, let’s add some new nodes to the graph:
create (a:Person {name:'A'})
create (b:Person {name:'B'})
create (c:Person {name:'C'})
create (d:Person {name:'D'})
create (a)-[:GIVES_MONEY]->(b)
create (b)-[:GIVES_MONEY]->(c)
create (c)-[:GIVES_MONEY]->(d)
match (a)-[:GIVES_MONEY]->(b)
return a,b
This results in :

We can run through the path from person A to person B, and change the property of the different nodes along the way.
MATCH p=(start)-[*]->(finish)
WHERE start.name = 'A' AND finish.name = 'D'
FOREACH (n IN nodes(p) | SET n.suspicious = false)
Within the FOREACH parentheses, you can do any of the updating commands: SET, REMOVE, CREATE, MERGE, DELETE, and FOREACH.
Last change: Oct 30, 2023