Neo4J:如何找到遍历列表中给定的多个节点的路径是否存在?
Neo4J: How can I find if a path traversing multiple nodes given in a list exist?
我有一个节点图,关系 NEXT 具有 2 个属性序列 (s) 和位置 ( p).例如:
N1-[NEXT{s:1, p:2}]-> N2-[NEXT{s:1, p:3}]-> N3-[NEXT{s:1, p:4}]-> N4
节点 N 可能有多个具有不同 属性 值的传出 Next 关系。
给定节点名称列表,例如[N2,N3,N4] 表示顺序路径,我想检查图形是否包含节点以及节点是否按顺序连接 Next。
例如,如果列表包含 [N2,N3,N4],则检查节点 N2,N3 和节点 N3,N4 之间是否存在 Next 关系。
此外,我想确保节点是同一序列的一部分,因此 属性 s 对于每个关系都是相同的 下一个。为了确保顺序得到维护,我需要验证 属性 p 是否是增量的。意思是,N2->N3关系中p的值是3,值p N3->N4之间为(3+1) = 4 依此类推
我尝试使用 APOC 使用 python(库:neo4jrestclient)从初始节点 N 检索可能的路径,然后使用以下查询手动处理路径以检查序列是否存在:
q = "MATCH (n:Node) WHERE n.name = 'N' CALL apoc.path.expandConfig(n {relationshipFilter:'NEXT>', maxLevel:4}) YIELD path RETURN path"
results = db.query(q,data_contents=True)
但是,运行 查询花费了一些时间,我最终停止了查询。有什么想法吗?
这个有点难。
首先,对路径中的节点进行预匹配。我们可以将这里收集到的节点作为路径中节点的白名单
假设起始节点包含在列表中,查询可能如下所示:
UNWIND $names as name
MATCH (n:Node {name:name})
WITH collect(n) as nodes
WITH nodes, nodes[0] as start, tail(nodes) as tail, size(nodes)-1 as depth
CALL apoc.path.expandConfig(start, {whitelistNodes:nodes, minLevel:depth, maxLevel:depth, relationshipFilter:'NEXT>'}) YIELD path
WHERE all(index in range(0, size(nodes)-1) WHERE nodes[index] = nodes(path)[index])
// we now have only paths with the given nodes in order
WITH path, relationships(path)[0].s as sequence
WHERE all(rel in tail(relationships(path)) WHERE rel.s = sequence)
// now each path only has relationships of common sequence
WITH path, apoc.coll.pairsMin([rel in relationships(path) | rel.p]) as pairs
WHERE all(pair in pairs WHERE pair[0] + 1 = pair[1])
RETURN path
我有一个节点图,关系 NEXT 具有 2 个属性序列 (s) 和位置 ( p).例如:
N1-[NEXT{s:1, p:2}]-> N2-[NEXT{s:1, p:3}]-> N3-[NEXT{s:1, p:4}]-> N4
节点 N 可能有多个具有不同 属性 值的传出 Next 关系。
给定节点名称列表,例如[N2,N3,N4] 表示顺序路径,我想检查图形是否包含节点以及节点是否按顺序连接 Next。
例如,如果列表包含 [N2,N3,N4],则检查节点 N2,N3 和节点 N3,N4 之间是否存在 Next 关系。
此外,我想确保节点是同一序列的一部分,因此 属性 s 对于每个关系都是相同的 下一个。为了确保顺序得到维护,我需要验证 属性 p 是否是增量的。意思是,N2->N3关系中p的值是3,值p N3->N4之间为(3+1) = 4 依此类推
我尝试使用 APOC 使用 python(库:neo4jrestclient)从初始节点 N 检索可能的路径,然后使用以下查询手动处理路径以检查序列是否存在:
q = "MATCH (n:Node) WHERE n.name = 'N' CALL apoc.path.expandConfig(n {relationshipFilter:'NEXT>', maxLevel:4}) YIELD path RETURN path"
results = db.query(q,data_contents=True)
但是,运行 查询花费了一些时间,我最终停止了查询。有什么想法吗?
这个有点难。
首先,对路径中的节点进行预匹配。我们可以将这里收集到的节点作为路径中节点的白名单
假设起始节点包含在列表中,查询可能如下所示:
UNWIND $names as name
MATCH (n:Node {name:name})
WITH collect(n) as nodes
WITH nodes, nodes[0] as start, tail(nodes) as tail, size(nodes)-1 as depth
CALL apoc.path.expandConfig(start, {whitelistNodes:nodes, minLevel:depth, maxLevel:depth, relationshipFilter:'NEXT>'}) YIELD path
WHERE all(index in range(0, size(nodes)-1) WHERE nodes[index] = nodes(path)[index])
// we now have only paths with the given nodes in order
WITH path, relationships(path)[0].s as sequence
WHERE all(rel in tail(relationships(path)) WHERE rel.s = sequence)
// now each path only has relationships of common sequence
WITH path, apoc.coll.pairsMin([rel in relationships(path) | rel.p]) as pairs
WHERE all(pair in pairs WHERE pair[0] + 1 = pair[1])
RETURN path