I have a question regarding the behavior of the ALL() predicate function in Neo4j 5.26.2. I have no issues with (1) and (2), however, I'm finding it unusual that I get 3 hits each with (3) and (4). Is this the correct behavior (as per specification)?
(1)
MATCH(p:Parent)
WHERE ALL(x IN p.array WHERE x = 2)
RETURN p.id, p.array
;
p.id p.array
2 [2, 2, 2]
(2)
MATCH(p:Parent)--(c)
WITH p, COLLECT(c.parent) AS parents
WHERE ALL(x IN parents WHERE x = 2)
RETURN p.id, parents
;
p.id parents
2 [2, 2, 2]
(3)
MATCH(p:Parent)
WHERE ALL(x IN p.empty_array WHERE x = 2)
RETURN p.id, p.empty_array
;
p.id p.empty_array
1 []
2 []
3 []
(4)
MATCH(p:Parent)--(c)
WITH p, COLLECT(c.does_not_exist) AS does_not_exists
WHERE ALL(x IN does_not_exists WHERE x = 2)
RETURN p.id, does_not_exists
;
p.id does_not_exists
1 []
2 []
3 []
You can create test data with the following Cypher statement:
WITH
RANGE(1,3) AS parents,
RANGE(1,3) AS children
FOREACH (parent IN parents |
MERGE (p:Parent{id:parent, array:[], empty_array:[]})
FOREACH (child IN children |
CREATE (c:Child{id:parent*10 + child, parent:parent})
MERGE (p)-[:CHILD]->(c)
SET p.array = p.array + parent
)
);
Displaying test data:
MATCH(p:Parent)--(c:Child)
RETURN *;
Deleting test data:
MATCH(p:Parent)--(c:Child)
DETACH DELETE p, c;
The all()
predicate function returns true for empty lists because it is vacuously true. It's consistent with the other predicate functions.
For example, the contradiction of all(x IN [] WHERE P(x))
is any(x IN [] WHERE P(x))
. In the latter case, there does not exist an x
for which P(x)
, and so it is always false.
For none(x IN [] WHERE Q(x))
, we can see it is equivalent to all(x IN [] WHERE NOT Q(x))
, and so it is also (vacuously) true.
See this example query:
RETURN all(x IN [] WHERE x > 0), // TRUE
none(x IN [] WHERE x > 0), // TRUE
any(x IN [] WHERE NOT x > 0) // FALSE