【问题标题】:Neo4J: How can I find if a path traversing multiple nodes given in a list exist?Neo4J:如何找到遍历列表中给定的多个节点的路径是否存在?
【发布时间】:2019-10-13 03:40:25
【问题描述】:

我有一个具有关系 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 对于每个关系 Next 都是相同的。为了确保订单保持不变,我需要验证属性 p 是否是增量的。意思是,N2->N3之间的关系中p的值为3,N3->N4之间的p值为(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"

结果 = db.query(q,data_contents=True)

但是,运行查询需要一些时间,我最终停止了查询。有什么想法吗?

【问题讨论】:

    标签: neo4j cypher neo4jrestclient


    【解决方案1】:

    这个有点难。

    首先,预匹配路径中的节点。我们可以将这里收集到的节点作为路径中节点的白名单

    假设起始节点包含在列表中,查询可能如下所示:

    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
    

    【讨论】:

    • 谢谢@InverseFalcon。当我添加 whitelistNodes:tail 时,查询在删除时不返回任何结果,知道为什么吗?此外,具有相同序列的节点之间可能存在多条路径,因此WITH path, apoc.coll.pairsMin([rel in relationships(path) | rel.p]) as pairs 行返回位置列表列表。例如:[["4","5"],["5,"1]] - [["77","78"],["78,"79]] - [["77"," 78"],["78,"74] ,如何编辑查询以循环遍历此列表并仅返回具有连续位置的路径?
    • 如果没有返回结果,那么这应该意味着没有depth 长度的可能路径,只包括那些节点。您可以尝试使用whitelistNodes:nodes,如果您没有使用最新的 APOC 版本,那么它不会跳过起始节点上的白名单过滤。
    • 这个 WHERE 子句应该为您执行连续过滤:WHERE all(pair in pairs WHERE pair[0] + 1 = pair[1])。这应该确保对于每个相邻的位置对,该对的第一个位置 +1 = 下一个位置。
    • 使用whitelistNodes:nodes 解决了它以及 p 是一个字符串,所以我将 where 子句修改为 WHERE all(成对配对 WHERE toInt(pair[0]) + 1 = toInt(pair[1])) 并且查询现在可以工作了。非常感谢,我很感激。
    猜你喜欢
    • 1970-01-01
    • 2017-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多