当子节点有多个父节点时,如何避免使用Neo4J/Cypher进行大量冗余路径分析?
这将返回距“id1”正好两代的所有唯一父代 当每个孩子只有一个家长时,这种方法很有效。但在我的数据中,一个节点可以有多个父节点(没有循环关系)。据当子节点有多个父节点时,如何避免使用Neo4J/Cypher进行大量冗余路径分析?,neo4j,cypher,Neo4j,Cypher,这将返回距“id1”正好两代的所有唯一父代 当每个孩子只有一个家长时,这种方法很有效。但在我的数据中,一个节点可以有多个父节点(没有循环关系)。据 PROFILE MATCH (:LevelOne {id: "id1"})-[:ISCHILDOF*2..2]->(parent:LevelTwo) RETURN DISTINCT parent ORDER BY parent.id 由于只有几千个节点,这将导致数以千万计的路径组合,并且由于资源耗尽而导致一致性故障 比如说, 如果“
PROFILE MATCH (:LevelOne {id: "id1"})-[:ISCHILDOF*2..2]->(parent:LevelTwo)
RETURN DISTINCT parent ORDER BY parent.id
由于只有几千个节点,这将导致数以千万计的路径组合,并且由于资源耗尽而导致一致性故障
比如说,
如果“id1”是节点A,并且您希望它的所有父节点都在三代之外,那么您将为每个子节点“通过”D节点两次:ABDF、ACDF
避免这种冗余的一种方法是一次查询一代,例如从以下内容开始:
MATCH (:LevelOne {id: "id1"})-[:ISCHILDOF]->(parent:LevelTwo)
RETURN DISTINCT parent ORDER BY parent.id
(不存在“*2..2”范围)
收集返回的父级,遍历它们以收集它们的ID,并使用它们查询下一代父级:
MATCH (:LevelOne {id: "id1"})-[:ISCHILDOF]->(parent:LevelTwo)
WHERE child.id IN [
'id1001',
'id1002',
'id1003',
'id1004',
'id1005',
'id1006',
'id1013',
'id1014',
'id1015',
'id1016',
'id1017']
RETURN DISTINCT parent
ORDER BY parent.id
根据需要对任意多个生成级别重复此操作
有没有更好、更标准的方法来实现这一点?[更新]
老祖宗
如果您只需要搜索最老一代的祖先,那么这种方法应该适用于您。很容易生成任意代数的查询
假设要搜索距离id
为“id1”的节点4代以外的祖先:
MATCH
子句的数量对应于生成的数量
将此方法演示5代
每一代的祖先(即使不是在通往最老一代的道路上)
如果您希望搜索每一代人的祖先,这种方法应该适用于您。下面的示例适用于4代人
注意:这种方法将列出每一代中的每一位祖先,甚至是那些不在通往最老一代的道路上的祖先
非常感谢。你能演示如何在多代人中返回祖先吗?我已经用一个数字对每一代的父代和祖先进行了后期修复(
parent1作为ancestor1
),但我不清楚如何返回的不仅仅是最深的祖先代(返回不同的parent5作为ancestor5
)。类似于-,虽然我知道这种语法是错误的-返回不同的ancestor2、ancestor3、ancestor4
。这要复杂得多-特别是如果您只想要沿着最老一代祖先的路径的祖先。查看每一代的所有祖先有点容易(但仍然很复杂)。我更新了我的答案,展示了如何查看每一代的所有祖先。感谢您的见解。我想我的选择是使用第一个查询,一次一代。
MATCH (:LevelOne {id: "id1"})-[:ISCHILDOF]->(parent:LevelTwo)
WHERE child.id IN [
'id1001',
'id1002',
'id1003',
'id1004',
'id1005',
'id1006',
'id1013',
'id1014',
'id1015',
'id1016',
'id1017']
RETURN DISTINCT parent
ORDER BY parent.id
MATCH (:LevelOne { id: "id1" })-[:ISCHILDOF]->(parent:LevelTwo)
WITH DISTINCT parent AS ancestor
MATCH (ancestor)-[:ISCHILDOF]->(parent:LevelTwo)
WITH DISTINCT parent AS ancestor
MATCH (ancestor)-[:ISCHILDOF]->(parent:LevelTwo)
WITH DISTINCT parent AS ancestor
MATCH (ancestor)-[:ISCHILDOF]->(parent:LevelTwo)
RETURN DISTINCT parent AS ancestor;
MATCH (:LevelOne { id: "id1" })-[:ISCHILDOF]->(parent:LevelTwo)
WITH COLLECT(DISTINCT parent) AS ancestors
WITH [ancestors] AS generations, ancestors UNWIND ancestors AS ancestor
MATCH (ancestor)-[:ISCHILDOF]->(parent:LevelTwo)
WITH generations, COLLECT(DISTINCT parent) AS ancestors
WITH generations+[ancestors] AS generations, ancestors UNWIND ancestors AS ancestor
MATCH (ancestor)-[:ISCHILDOF]->(parent:LevelTwo)
WITH generations, COLLECT(DISTINCT parent) AS ancestors
WITH generations+[ancestors] AS generations, ancestors UNWIND ancestors AS ancestor
MATCH (ancestor)-[:ISCHILDOF]->(parent:LevelTwo)
WITH generations, COLLECT(DISTINCT parent) AS ancestors
RETURN generations+[ancestors] AS generations;