Neo4j:查找所有节点指向的节点集

Neo4j: Find set of nodes that all nodes point to

更准确地说,假设您有 People 和 Animal 节点,以及从 PersonAnimal:likes 关系。问题是:我怎样才能找到 所有 人们喜欢的所有 Animal

示例:

(Person {name: "Jake"})-[:likes]->(Animal {name: "Dog"})
(Person {name: "Maya"})-[:likes]->(Animal {name: "Dog"})
(Person {name: "Maya"})-[:likes]->(Animal {name: "Snake"})
(Person {name: "Jake"})-[:likes]->(Animal {name: "Cat"})

如果杰克和玛雅是人的宇宙,那么杰克和玛雅都喜欢的动物集合只包含狗。

使用此示例数据集:

CREATE (jake:Person {name:'Jake'}),
       (maya:Person {name:'Maya'}),
       (dog:Animal {name:'Dog'}),
       (snake:Animal {name:'Snake'}),
       (cat:Animal {name:'Cat'}),
       (jake)-[:LIKES]->(dog),
       (jake)-[:LIKES]->(cat),
       (maya)-[:LIKES]->(dog),
       (maya)-[:LIKES]->(snake)

我觉得下面的读起来不错:

MATCH (p:Person)
MATCH (a:Animal)

WITH a, COLLECT(p) AS people
WHERE ALL(p IN people WHERE (p)-[:LIKES]->(a))
RETURN a.name

http://console.neo4j.org/r/vu3vxp

但速度不如:

MATCH (p:Person)
WITH COUNT(p) AS people

MATCH (p:Person)-[:LIKES]->(a:Animal)
WITH a, COUNT(p) AS likes, people
WHERE likes = people
RETURN a.name

http://console.neo4j.org/r/nnrvj2

所有人都喜欢的一组动物(称其为"A")必须与单身个人喜欢的一组动物相同或为该组动物的子集喜欢。因此,我们可以通过仅测试随机人喜欢的动物来加快对 A 的搜索。

以下查询计算人数 (np),获取单个人喜欢的动物集合 (ca),以及 returns 该集合中被喜欢的动物(如果有) np人.

MATCH (p:Person)
WITH COUNT(p) AS np

MATCH (p:Person)-[:LIKES]->(a:Animal)
WITH p, COLLECT(a) AS ca, np
LIMIT 1

UNWIND ca AS a
MATCH (x:Person)-[:LIKES]->(a)
WITH a, COUNT(x) AS nx, np
WHERE nx = np
RETURN COLLECT(a) AS result;