12.3. Collection functions

Collection functions return collections of things — nodes in a path, and so on.

See also the section called “Collection operators”.

Figure 12.3. Graph

NODES

Returns all nodes in a path.

Syntax: NODES( path )

Arguments:

  • path: A path.

Query. 

MATCH p=(a)-->(b)-->(c)
WHERE a.name='Alice' AND c.name='Eskil'
RETURN nodes(p)

All the nodes in the path p are returned by the example query.

Result

nodes(p)
1 row

[Node[2]{name:"Alice",age:38,eyes:"brown"},Node[3]{name:"Bob",age:25,eyes:"blue"},Node[1]{name:"Eskil",age:41,eyes:"blue",array:["one","two","three"]}]

Try this query live. create (_0 {`age`:54, `eyes`:"brown", `name`:"Daniel"}) create (_1:`Spouse` {`age`:41, `array`:["one", "two", "three"], `eyes`:"blue", `name`:"Eskil"}) create (_2:`foo`:`bar` {`age`:38, `eyes`:"brown", `name`:"Alice"}) create (_3 {`age`:25, `eyes`:"blue", `name`:"Bob"}) create (_4 {`age`:53, `eyes`:"green", `name`:"Charlie"}) create _2-[:`KNOWS`]->_4 create _2-[:`KNOWS`]->_3 create _3-[:`KNOWS`]->_0 create _3-[:`MARRIED`]->_1 create _4-[:`KNOWS`]->_0 match p=(a)-->(b)-->(c) where a.name='Alice' and c.name='Eskil' return nodes(p)

RELATIONSHIPS

Returns all relationships in a path.

Syntax: RELATIONSHIPS( path )

Arguments:

  • path: A path.

Query. 

MATCH p=(a)-->(b)-->(c)
WHERE a.name='Alice' AND c.name='Eskil'
RETURN relationships(p)

All the relationships in the path p are returned.

Result

relationships(p)
1 row

[:KNOWS[0]{},:MARRIED[4]{}]

Try this query live. create (_0 {`age`:54, `eyes`:"brown", `name`:"Daniel"}) create (_1:`Spouse` {`age`:41, `array`:["one", "two", "three"], `eyes`:"blue", `name`:"Eskil"}) create (_2:`foo`:`bar` {`age`:38, `eyes`:"brown", `name`:"Alice"}) create (_3 {`age`:25, `eyes`:"blue", `name`:"Bob"}) create (_4 {`age`:53, `eyes`:"green", `name`:"Charlie"}) create _2-[:`KNOWS`]->_4 create _2-[:`KNOWS`]->_3 create _3-[:`KNOWS`]->_0 create _3-[:`MARRIED`]->_1 create _4-[:`KNOWS`]->_0 match p=(a)-->(b)-->(c) where a.name='Alice' and c.name='Eskil' return relationships(p)

LABELS

Returns a collection of string representations for the labels attached to a node.

Syntax: LABELS( node )

Arguments:

  • node: Any expression that returns a single node

Query. 

MATCH (a)
WHERE a.name='Alice'
RETURN labels(a)

The labels of n is returned by the query.

Result

labels(a)
1 row

["foo","bar"]

Try this query live. create (_0 {`age`:54, `eyes`:"brown", `name`:"Daniel"}) create (_1:`Spouse` {`age`:41, `array`:["one", "two", "three"], `eyes`:"blue", `name`:"Eskil"}) create (_2:`foo`:`bar` {`age`:38, `eyes`:"brown", `name`:"Alice"}) create (_3 {`age`:25, `eyes`:"blue", `name`:"Bob"}) create (_4 {`age`:53, `eyes`:"green", `name`:"Charlie"}) create _2-[:`KNOWS`]->_4 create _2-[:`KNOWS`]->_3 create _3-[:`KNOWS`]->_0 create _3-[:`MARRIED`]->_1 create _4-[:`KNOWS`]->_0 match (a) where a.name='Alice' return labels(a)

EXTRACT

To return a single property, or the value of a function from a collection of nodes or relationships, you can use EXTRACT. It will go through a collection, run an expression on every element, and return the results in an collection with these values. It works like the map method in functional languages such as Lisp and Scala.

Syntax: EXTRACT( identifier in collection | expression )

Arguments:

  • collection: An expression that returns a collection
  • identifier: The closure will have an identifier introduced in it’s context. Here you decide which identifier to use.
  • expression: This expression will run once per value in the collection, and produces the result collection.

Query. 

MATCH p=(a)-->(b)-->(c)
WHERE a.name='Alice' AND b.name='Bob' AND c.name='Daniel'
RETURN extract(n IN nodes(p)| n.age) AS extracted

The age property of all nodes in the path are returned.

Result

extracted
1 row

[38,25,54]

Try this query live. create (_0 {`age`:54, `eyes`:"brown", `name`:"Daniel"}) create (_1:`Spouse` {`age`:41, `array`:["one", "two", "three"], `eyes`:"blue", `name`:"Eskil"}) create (_2:`foo`:`bar` {`age`:38, `eyes`:"brown", `name`:"Alice"}) create (_3 {`age`:25, `eyes`:"blue", `name`:"Bob"}) create (_4 {`age`:53, `eyes`:"green", `name`:"Charlie"}) create _2-[:`KNOWS`]->_4 create _2-[:`KNOWS`]->_3 create _3-[:`KNOWS`]->_0 create _3-[:`MARRIED`]->_1 create _4-[:`KNOWS`]->_0 match p=(a)-->(b)-->(c) where a.name='Alice' and b.name='Bob' and c.name='Daniel' return extract(n in nodes(p) | n.age) AS extracted

FILTER

FILTER returns all the elements in a collection that comply to a predicate.

Syntax: FILTER(identifier in collection WHERE predicate)

Arguments:

  • collection: An expression that returns a collection
  • identifier: This is the identifier that can be used from the predicate.
  • predicate: A predicate that is tested against all items in the collection.

Query. 

MATCH (a)
WHERE a.name='Eskil'
RETURN a.array, filter(x IN a.array WHERE length(x)= 3)

This returns the property named array and a list of values in it, which have the length 3.

Result

a.arrayfilter(x in a.array WHERE length(x) = 3)
1 row

["one","two","three"]

["one","two"]

Try this query live. create (_0 {`age`:54, `eyes`:"brown", `name`:"Daniel"}) create (_1:`Spouse` {`age`:41, `array`:["one", "two", "three"], `eyes`:"blue", `name`:"Eskil"}) create (_2:`foo`:`bar` {`age`:38, `eyes`:"brown", `name`:"Alice"}) create (_3 {`age`:25, `eyes`:"blue", `name`:"Bob"}) create (_4 {`age`:53, `eyes`:"green", `name`:"Charlie"}) create _2-[:`KNOWS`]->_4 create _2-[:`KNOWS`]->_3 create _3-[:`KNOWS`]->_0 create _3-[:`MARRIED`]->_1 create _4-[:`KNOWS`]->_0 match (a) where a.name='Eskil' return a.array, filter(x in a.array WHERE length(x) = 3)

TAIL

TAIL returns all but the first element in a collection.

Syntax: TAIL( expression )

Arguments:

  • expression: This expression should return a collection of some kind.

Query. 

MATCH (a)
WHERE a.name='Eskil'
RETURN a.array, tail(a.array)

This returns the property named array and all elements of that property except the first one.

Result

a.arraytail(a.array)
1 row

["one","two","three"]

["two","three"]

Try this query live. create (_0 {`age`:54, `eyes`:"brown", `name`:"Daniel"}) create (_1:`Spouse` {`age`:41, `array`:["one", "two", "three"], `eyes`:"blue", `name`:"Eskil"}) create (_2:`foo`:`bar` {`age`:38, `eyes`:"brown", `name`:"Alice"}) create (_3 {`age`:25, `eyes`:"blue", `name`:"Bob"}) create (_4 {`age`:53, `eyes`:"green", `name`:"Charlie"}) create _2-[:`KNOWS`]->_4 create _2-[:`KNOWS`]->_3 create _3-[:`KNOWS`]->_0 create _3-[:`MARRIED`]->_1 create _4-[:`KNOWS`]->_0 match (a) where a.name='Eskil' return a.array, tail(a.array)

RANGE

Returns numerical values in a range with a non-zero step value step. Range is inclusive in both ends.

Syntax: RANGE( start, end [, step] )

Arguments:

  • start: A numerical expression.
  • end: A numerical expression.
  • step: A numerical expression.

Query. 

RETURN range(0,10), range(2,18,3)

Two lists of numbers are returned.

Result

range(0,10)range(2,18,3)
1 row

[0,1,2,3,4,5,6,7,8,9,10]

[2,5,8,11,14,17]

Try this query live. create (_0 {`age`:54, `eyes`:"brown", `name`:"Daniel"}) create (_1:`Spouse` {`age`:41, `array`:["one", "two", "three"], `eyes`:"blue", `name`:"Eskil"}) create (_2:`foo`:`bar` {`age`:38, `eyes`:"brown", `name`:"Alice"}) create (_3 {`age`:25, `eyes`:"blue", `name`:"Bob"}) create (_4 {`age`:53, `eyes`:"green", `name`:"Charlie"}) create _2-[:`KNOWS`]->_4 create _2-[:`KNOWS`]->_3 create _3-[:`KNOWS`]->_0 create _3-[:`MARRIED`]->_1 create _4-[:`KNOWS`]->_0 return range(0,10), range(2,18,3)

REDUCE

To run an expression against individual elements of a collection, and store the result of the expression in an accumulator, you can use REDUCE. It will go through a collection, run an expression on every element, storing the partial result in the accumulator. It works like the fold or reduce method in functional languages such as Lisp and Scala.

Syntax: REDUCE( accumulator = initial, identifier in collection | expression )

Arguments:

  • accumulator: An identifier that will hold the result and the partial results as the collection is iterated
  • initial: An expression that runs once to give a starting value to the accumulator
  • collection: An expression that returns a collection
  • identifier: The closure will have an identifier introduced in it’s context. Here you decide which identifier to use.
  • expression: This expression will run once per value in the collection, and produces the result value.

Query. 

MATCH p=(a)-->(b)-->(c)
WHERE a.name='Alice' AND b.name='Bob' AND c.name='Daniel'
RETURN reduce(totalAge = 0, n IN nodes(p)| totalAge + n.age) AS reduction

The age property of all nodes in the path are summed and returned as a single value.

Result

reduction
1 row

117

Try this query live. create (_0 {`age`:54, `eyes`:"brown", `name`:"Daniel"}) create (_1:`Spouse` {`age`:41, `array`:["one", "two", "three"], `eyes`:"blue", `name`:"Eskil"}) create (_2:`foo`:`bar` {`age`:38, `eyes`:"brown", `name`:"Alice"}) create (_3 {`age`:25, `eyes`:"blue", `name`:"Bob"}) create (_4 {`age`:53, `eyes`:"green", `name`:"Charlie"}) create _2-[:`KNOWS`]->_4 create _2-[:`KNOWS`]->_3 create _3-[:`KNOWS`]->_0 create _3-[:`MARRIED`]->_1 create _4-[:`KNOWS`]->_0 match p=(a)-->(b)-->(c) where a.name='Alice' and b.name='Bob' and c.name='Daniel' return reduce(totalAge = 0, n in nodes(p) | totalAge + n.age) AS reduction