返回属于Neo4j密码列表的关系



这个数据集包含3M个节点和超过5M个关系。大约有8种不同的关系类型。现在我想返回2个节点,如果它们是相互连接的。这里的两个节点是A &B和我想看看它们是否相互联系。

MATCH (n:WCD_Ent)
USING INDEX n:WCD_Ent(WCD_NAME)
WHERE n.WCD_NAME = "A"
MATCH (m:WCD_Ent)
USING INDEX m:WCD_Ent(WCD_NAME)
WHERE m.WCD_NAME = "B"
MATCH (n) - [r*] - (m)
RETURN n,r,m

这导致Java堆空间错误。

我希望在查询中放入的另一个条件是,如果2个节点A&B之间的关系至少包含一个特定的关系类型(NAME_MATCH)一次。A你能帮我解决这个问题吗?

Gabor的建议是最重要的修复;这样做会占用堆空间,因为首先要生成行的笛卡尔积,然后使用模式进行过滤。使用该模式生成行,您将更有效地利用空间。如果在WCD_Ent(WCD_NAME)上有索引,也不需要指定索引;只有当查询运行非常慢,并且PROFILE显示查询计划器跳过索引时,才需要执行此操作。试试这个:

MATCH (n:WCD_Ent { WCD_NAME: "A" })-[r*..5]-(m:WCD_Ent { WCD_NAME: "B" })
WHERE ANY(rel IN r WHERE TYPE(rel) = 'NAME_MATCH')
RETURN n, r, m

这里的WHERE过滤器将检查r中的所有关系(这是一个集合,您分配它的方式),并确保其中至少有一个匹配所需的类型。

Tore的答案(包括变量关系上界)是寻找两个节点是否连接以及连接它们的路径中是否存在某种关系的最佳答案。

迄今为止给出的大多数解决方案的一个缺点是对变量关系匹配没有限制,这意味着查询将爬行整个图,试图在所有可能的路径上匹配,而不是只检查一个这样的路径存在然后停止。这可能是导致堆空间错误的原因。

Tore建议在你的匹配中添加可变长度关系的上限是一个很好的解决方案,因为它也有助于在两个节点没有连接的情况下,防止你不得不爬行整个图。在任何情况下,上界都应防止堆爆炸。

这里有更多的可能性。我省略了关系的上界,但如果需要,可以很容易地添加。

// this one won't check for the particular relationship type in the path
// but doesn't need to match on all possible paths, just find connectedness
MATCH (n:WCD_Ent { WCD_NAME: "A" }), (m:WCD_Ent { WCD_NAME: "B" })
RETURN EXISTS((n)-[*]-(m))
// using shortestPath() will only give you a single path back that works
// however WHERE ANY may be a filter to apply after matches are found
// so this may still blow up, not sure
MATCH (n:WCD_Ent { WCD_NAME: "A" }), (m:WCD_Ent { WCD_NAME: "B" })
RETURN shortestPath((n)-[r*]-(m))
WHERE ANY(rel IN r WHERE TYPE(rel) = 'NAME_MATCH')
// Adding LIMIT 1 will only return one path result
// Unsure if this will prevent the heap from blowing up though
// The performance and outcome may be identical to the above query
MATCH (n:WCD_Ent { WCD_NAME: "A" }), (m:WCD_Ent { WCD_NAME: "B" })
MATCH (n)-[r*]-(m)
WHERE ANY(rel IN r WHERE TYPE(rel) = 'NAME_MATCH')
RETURN n, r, m
LIMIT 1

一些增强:

  1. 可以在模式中绑定属性值,而不是WHERE条件。
  2. 您可以将三个MATCH条件合并为一个条件,这样可以确保查询引擎不会计算nm的笛卡尔积。(您也可以使用EXPLAIN将查询计划可视化并检查。)

结果查询:

MATCH (n:WCD_Ent { WCD_NAME: "A" })-[r*]-(m:WCD_Ent { WCD_NAME: "B" })
RETURN n, r, m

更新:Tore Eschliman指出你不需要指定索引,所以我从查询中删除了这两行:

USING INDEX n:WCD_Ent(WCD_NAME)
USING INDEX m:WCD_Ent(WCD_NAME)

最新更新