匹配仅与两个特定节点相关的所有节点

时间:2017-03-07 00:44:17

标签: neo4j

我有100个带有标签A的节点和2个带有标签B的节点。所有带有标签A的节点都与至少一个带有标签B的节点相关。如何获得与标签B的两个节点相关的标签A的所有节点?我尝试过以下方法:

MATCH p=(:A)-[:TYPE]->(b:B) where b.Name = 'XYZ' or b.Name = 'ABC'
RETURN p

这只给了我与这两个节点相关的所有节点。

编辑:我设法通过使用以下查询来完成此操作:

MATCH (a:A)- [:TYPE] ->(t:Type) where t.Name = 'ABC'
MATCH (a:A)- [:TYPE] -> (u:Type) where u.Name = 'XYZ'
return a, t, u

有没有办法对此进行优化?

2 个答案:

答案 0 :(得分:5)

有几种方法可以做到这一点。

如果:TYPE关系:A节点只连接到:B节点,并且每个节点之间只有一个:TYPE关系:A和:B节点,那么最快的方法是根据以下程度过滤:TYPE关系来自:节点:

MATCH (a:A)
WHERE SIZE((a)-[:TYPE]->()) = 2
RETURN a

如果:TYPE关系不仅仅是:B节点,那么您可以稍微更改查询。它不会那么高效,但它会正常工作:

MATCH (a:A)
WHERE SIZE((a)-[:TYPE]->(:B)) = 2
RETURN a

如果B节点的数量增加,并且您想要找到:连接到所有:B节点的节点,那么我们可以使用集合以及ALL()函数来获取正确的集合:A节点:

MATCH (b:B)
WITH COLLECT(b) as bnodes
MATCH (a:A)
WHERE ALL(b in bnodes WHERE (b)<-[:TYPE]-(a))
RETURN a

如果您只需要B节点的一部分而不是全部,那么您可以根据一组ID过滤您的初始匹配:

// assuming you supply a list parameter of ids called 'ids'
MATCH (b:B)
WHERE b.id in {ids}
WITH COLLECT(b) as bnodes
WITH HEAD(bnodes) as first, bnodes
MATCH (a)-[:TYPE]->(first)
WHERE ALL(b in TAIL(bnodes) WHERE (b)<-[:TYPE]-(a))
RETURN a

在那里有一些额外的逻辑只考虑:一个节点是你的bnodes中的一个元素的类型。这样我们就不会考虑:与您的任何bnode无关的节点,使我们无法进行不必要的比较。

答案 1 :(得分:0)

试试这个。

MATCH

这里不能有一个(a:A)查询,因为在具有2个不同名称的一个节点上进行过滤将不起作用。另请注意,您可以将变量分配给实例示例$arr = array(9, 4, -3, -10); 并返回它们或根据需要执行进一步操作。