I have the following node structure: (:Patch)-[:INCLUDES]->(:Roster)-[:HAS]->(:PublicList)-[:INCLUDES]->(u:Unit)
Then I have an array of :Unit
ids: [197, 196, 19, 20, 191, 171, 3, 174, 194, 185]
I would like to check whether a :PublicList
that has the :INCLUDES
relationship to all the :Unit
ids in the list already exists.
I tried writing a COUNT
and MATCH
query like this, but this just seems like an error-prone long-winded approach:
MATCH (p:Patch)-[:INCLUDES]->(r:Roster)-[:HAS]-(d:PublicList)
WITH COLLECT(d) as drafts
UNWIND drafts as draft
WITH draft
UNWIND [197, 196, 19, 20, 191, 171, 3, 174, 194, 185] as unitID
MATCH (draft)-[:INCLUDES]->(u:Unit)
WHERE id(u) = unitID
WITH count(DISTINCT u) as draftUnits
WITH COLLECT(draftUnits) as matchCounts
RETURN matchCounts
Can someone help me write this so it returns a boolean if a :PublicList
has a:INCLUDES
relationship to all the IDs in the list?
I suggest to first match the units, put them into a collection and then use the ALL
predicate to check that the PublicList has a connection to all units.
MATCH (n:Unit) WHERE id(n) IN [197, 196, 19, 20, 191, 171, 3, 174, 194, 185]
WITH collect(n) AS units
MATCH (p:Patch)-[:INCLUDES]->(r:Roster)-[:HAS]-(d:PublicList)
WHERE ALL(x IN units WHERE (d)-[:INCLUDES]->(x))
RETURN count(*) AS matchCount
If you want to return the PublicList along with a boolean value if it matches all of them, you can slightly adjust like this
MATCH (n:Unit) WHERE id(n) IN [197, 196, 19, 20, 191, 171, 3, 174, 194, 185]
WITH collect(n) AS units
MATCH (p:Patch)-[:INCLUDES]->(r:Roster)-[:HAS]-(d:PublicList)
RETURN d, ALL(x IN units WHERE (d)-[:INCLUDES]->(x)) as matchAll