我有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
有没有办法对此进行优化?
答案 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);
并返回它们或根据需要执行进一步操作。