I need to fetch two related collections from a Neo4j database.
The first one is to get some things that satisfy a list of conditions, something like this:
MATCH (n:Thing)
WHERE [complicated list of conditions]
RETURN n
ORDER BY n.label
LIMIT 25
the second one is to get nodes related to the nodes that satisfy the conditions, something like this:
MATCH (m:RelatedThing) -[:Relationship]-(n:Thing)
WHERE [same complicated conditions about n]
RETURN m
ORDER BY m.label
LIMIT 25
Crucially, the m's don't have to be related to the first 25 n's that were returned by query 1.
It seems like there is a lot of repetition between these two queries. Is there a way to run them both in a single query?
Obviously this can be done in two queries, but reading around I haven't found a good way to run both queries together. It seems like maybe COLLECT could be useful, but it doesn't quite fit the use case.
EDIT: I am looking for a solution that works in version 3.5.12
You can use two CALL subqueries:
MATCH (n:Thing) WHERE < complicated list of conditions >
WITH COLLECT(n) AS list
CALL {
WITH list
UNWIND list AS x
WITH x
ORDER BY x.label LIMIT 25
RETURN COLLECT(x) AS list1
}
CALL {
WITH list
UNWIND list AS y
MATCH (m:RelatedThing)-[:Relationship]-(y)
WITH DISTINCT m
ORDER BY m.label LIMIT 25
RETURN COLLECT(m) AS list2
}
RETURN list1, list2
The APOC procedure apoc.cypher.run
has been supported for a long time, and can be used instead of the more recent CALL subquery
feature:
MATCH (n:Thing) WHERE < complicated list of conditions >
WITH COLLECT(n) AS list
CALL apoc.cypher.run("
UNWIND list AS x
WITH x
ORDER BY x.label LIMIT 25
RETURN COLLECT(x) AS list1",
{list: list}
) YIELD value as val1
CALL apoc.cypher.run("
UNWIND list AS y
MATCH (m:RelatedThing)-[:Relationship]-(y)
WITH DISTINCT m
ORDER BY m.label LIMIT 25
RETURN COLLECT(m) AS list2",
{list: list}
) YIELD value as val2
RETURN val1.list1 AS list1, val2.list2 AS list2