Half of Cypher's magic is in transformation between different groupings of data. This really boils down to one big matrix, which can be thought of like a table.
- Any operation will act on one "row" at a time, until it has done all rows.
- Any variable or property in that row can be a list.
- Aggregation functions, and things like
COLLECT
take multiple rows, and turn them into one variable in one row. - An expression is a part of a Cypher command which "chooses" specific variables from a row.
-
WITH
chooses specific variables to pull from all rows, and use in following commands. -
UNWIND
turns a list (or collection) into rows.
So, to answer your question, if you're working with a list, or collection, you have two choises:
- Use
UNWIND
to turn the list into rows, then you can apply aggregation functions likeavg()
. - Use list functions like
REDUCE()
to collapse the list into a single variable.
UNWIND
WITH [1, 2, 3, 4, 5] AS list1
UNWIND list1 AS vals
RETURN avg(vals) AS average
In this example, we're turning list1
into a bunch of "rows," where each entry in the list is now referenced by the vals
variable. The expressions passed to the avg
function is selecting all instances of vals
as input to avg
.
REDUCE
WITH [1, 2, 3, 4, 5] AS list1
RETURN REDUCE(sum = 0, val IN list1 | sum + val) / SIZE(list1) AS average
Instead of turning the list into a set of rows, we're stepping through all entries in the list, doing some math, and spitting out the result. Essentially creating our own avg function for operating on lists.
Apoc wins everything
No matter what you're doing, APOC probably has a clean, fast, tool that will perfectly fit your need. This case included. Enter, APOC Collection Functions
WITH [1,2,3,4,5] AS list1
RETURN apoc.coll.avg(list1) AS average
See Also: cypher - How to use average function in neo4j with collection - Stack Overflow