我有这个包含3M节点和超过5M关系的数据集。大约有8种不同的关系类型。现在我想返回2个节点,如果它们是相互连接的。这里有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堆空间错误。
我希望在我的查询中提出的另一个条件是两个节点A和B之间的关系是否至少包含一个特定的关系类型(NAME_MATCH)。你能帮我解决一下吗?
答案 0 :(得分:1)
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
中的所有关系(这是一个集合,您指定的方式)并确保其中至少有一个符合所需的关系类型。
答案 1 :(得分:1)
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
答案 2 :(得分:0)
一些增强功能:
WHERE
条件。MATCH
条件合并为一个条件,这样可以确保查询引擎不会计算n
和m
的笛卡尔积。 (您也可以使用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)