string aggregation in Cypher
I need an equivalent of Postgres string_agg
, Oracle listagg
or MySQL group_concat
in Cypher. My Cypher query is a stored procedure returning stream of strings (in following minimized example replaced by collection unwind). As a result, I want to get single string with concatenation of all strings.
Example:
UNWIND ['first','second','third'] as c
RETURN collect(c)
Actual result (of list type):
["first", "second", "third"]
Expected result (of String type):
"firstsecondthird"
or (nice-to-have):
"firstCUSTOMSEPARATORsecondCUSTOMSEPARATORthird"
(I just wanted to quickly build ad hoc query to verify some postprocessing actually performed by Neo4j consumer and I thought it would be simple but I cannot find any solution. Unlike this answer I want string, not collection, since my issue is in something about length of concatenated string.)
How about using APOC ?
UNWIND ['first','second','third'] as c
RETURN apoc.text.join(collect(c), '-') AS concat
Where -
is your custom separator.
Result :
╒════════════════════╕
│"concat" │
╞════════════════════╡
│"first-second-third"│
└────────────────────┘
--
NO APOC
Take into account when the collection is one element only
UNWIND ['first','second','third'] as c
WITH collect(c) AS elts
RETURN CASE WHEN size(elts) > 1
THEN elts[0] + reduce(x = '', z IN tail(elts) | x + '-' + z)
ELSE elts[0]
END
You can further simplify the query as below. And no need to worry if list is empty and it will return null if l is empty list
WITH ['first','second','third'] as l
RETURN REDUCE(s = HEAD(l), n IN TAIL(l) | s + n) AS result