cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Strange syntax, sqaure brackets, vertical bar

rekursivs
Node

Hello,
I'm new to Neo4j Cypher, trying to understand all the basics of syntax.
Found this code (source page here)

 

MATCH (p:Person) WITH collect(distinct p.country) as countries
WITH [cName IN countries | apoc.create.vNode(['Country'],{name:cName})] as countryNodes
WITH apoc.map.groupBy(countryNodes,'name') as countries
MATCH (p1:Person)-[:KNOWS]->(p2:Person)
WITH p1.country as cFrom, p2.country as cTo, count(*) as count, countries
RETURN countries[cFrom] as from, countries[cTo] as to, apoc.create.vRelationship(countries[cFrom],'KNOWS',{count:count},countries[cTo]) as rel;

 

Can't figure out how line 2 of the code works.
If I split it into blocks, it starts with the WITH keyword, and ends with a variable name:

 

WITH [] as countryNodes

 

Alright, so far so good. Variable countryNodes gets assigned some value that's coming from the square brackets.
But what do those square brackets do?

 

[cName IN countries | apoc.create.vNode(['Country'],{name:cName})]

 

I cannot find any manual page that suggests a syntax like this:

 

[ expression | expression ]

 

I would appreciate if someone could explain this and also provide some hints to documentation (if that is a documented syntax).

1 ACCEPTED SOLUTION

glilienfield
Ninja
Ninja

It’s list comprehension syntax.  Take the following:

[x in aList | someFunction(x)] as y

what this does is take the list represented by ‘aList’ and transforms it element-by-element to a new list, which is bound to variable ‘y’. The transformation is the someFunction that you specify. In your example, the code is using an APOC function to transform element ‘x’. Another example is converting a list of nodes into a list of values represented by a single property of the nodes. For example, 

[x in nodeList | x.name] 

this will create a new list consisting of just the value of the name property of each node in the list. 
list comprehension is one of my favorite tools. You can even add a filtering predicate, so you can extract specific elements from the list. For example, 

[x in nodeList where x.age > 20 | x.name]
will return a list of the names for nodes in nodeList that have an age greater than 20.  Both the filter and mapping parts are optional. 

https://neo4j.com/docs/cypher-manual/current/syntax/lists/

map comprehension is equally cool. 

View solution in original post

2 REPLIES 2

glilienfield
Ninja
Ninja

It’s list comprehension syntax.  Take the following:

[x in aList | someFunction(x)] as y

what this does is take the list represented by ‘aList’ and transforms it element-by-element to a new list, which is bound to variable ‘y’. The transformation is the someFunction that you specify. In your example, the code is using an APOC function to transform element ‘x’. Another example is converting a list of nodes into a list of values represented by a single property of the nodes. For example, 

[x in nodeList | x.name] 

this will create a new list consisting of just the value of the name property of each node in the list. 
list comprehension is one of my favorite tools. You can even add a filtering predicate, so you can extract specific elements from the list. For example, 

[x in nodeList where x.age > 20 | x.name]
will return a list of the names for nodes in nodeList that have an age greater than 20.  Both the filter and mapping parts are optional. 

https://neo4j.com/docs/cypher-manual/current/syntax/lists/

map comprehension is equally cool. 

Thank you for such an explanatory reply. This was exactly what I was missing!
🙏

Nodes 2022
Nodes
NODES 2022, Neo4j Online Education Summit

All the sessions of the conference are now available online