使用 Cypher 以递增的关系权重顺序遍历 Neo4j 图

Traversing Neo4j graph in increasing order of relationship weights using Cypher

考虑一下我有以下带有边权重的图表:

我想知道我是否可以使用 CYPHER 执行从节点 a 开始的遍历,然后按照权重的递增顺序执行遍历。也就是上面应该return(a)-4->(e)-3->(c)-3->(d)

这可以使用密码吗?

您的描述略有错误(根据您的示例),因为您不想遍历具有增加权重的关系,您想要遍历关系每一步的 最大 权重。

您不能在 Cypher 中以通用方式执行此操作,因为结果是迭代构建的,并且您无法知道结果路径的最大长度。

在 Cypher 中,您必须

  1. 构建所有路径
  2. 按第一个关系的权重过滤它们
  3. 通过第二个关系的权重过滤剩余的(如果存在)
  4. 等等

Cypher 的声明性本质并不真正兼容:它会很麻烦,而且可能也很慢。构建一个 procedure or function (in the upcoming Neo4j 3.1) traversing the longest path(s), with the PathExpander 只返回当前节点具有最大权重的关系会容易得多。

正如@FrankPavageau 所说,在 Java 中编写解决方案可能更简单、更快。然而,通过利用现有的 APOC 过程 apoc.periodic.commit,您不必在 Java.

中实现任何内容

apoc.periodic.commit 将重复执行 Cypher 查询 直到它 return 的值为 0 或根本没有结果 。这是一个如何使用它来解决您的问题的示例。

首先,让我们创建您的示例数据:

CREATE (a:Foo {id: 'a'}), (b:Foo {id: 'b'}), (c:Foo {id: 'c'}), (d:Foo {id: 'd'}), (e:Foo {id: 'e'}), (f:Foo {id: 'f'}), (g:Foo {id: 'g'}),
  (a)-[:NEXT {value: 3}]->(b),
  (a)-[:NEXT {value: 4}]->(e),
  (e)-[:NEXT {value: 3}]->(c),
  (e)-[:NEXT {value: 1}]->(f),
  (e)-[:NEXT {value: 2}]->(g),
  (c)-[:NEXT {value: 3}]->(d),
  (c)-[:NEXT {value: 2}]->(g);

此技术涉及您的 3 个查询:

  1. 创建带有 Temp 标签的临时节点的查询(在下面的步骤 2 中执行的重复执行之间保持状态,并保存最终结果)。 (在示例数据中,起始节点的 ida。)

    MERGE (temp:Temp)
    SET temp = {values: [], ids: ['a']};
    
  2. 调用 apoc.periodic.commit 的查询以重复执行传递的 Cypher 语句。每次执行 Cypher 语句时,它都会从最后找到的节点(idtemp.ids 尾端的节点)开始,并尝试找到关系最高的下一个节点value 值。如果最后一个节点是叶节点,那么 Cypher 语句 return 什么都没有(因为第二个 MATCH 将失败,中止该语句)——这将终止该过程;否则,Cypher 语句会将 max 值附加到 temp.values 并将相应的节点 id 附加到 temp.ids,并且 return 1.

    CALL apoc.periodic.commit("
      MATCH (temp:Temp)
      MATCH (:Foo {id: LAST(temp.ids)})-[n:NEXT]->(f:Foo)
      WITH temp, REDUCE(s = {max: 0}, x IN COLLECT({v: n.value, id: f.id}) |
        CASE WHEN x.v > s.max
          THEN {max: x.v, id: x.id}
          ELSE s
        END
      ) AS curr
      SET temp.values = temp.values + curr.max, temp.ids = temp.ids + curr.id
      RETURN 1;
    ", NULL);
    
  3. 查询得到最终结果。 ids 集合将是沿 "maximum path" 的节点的 ID,而 values 集合将是沿同一路径的 NEXT 关系的 values .

    MATCH (temp:Temp)
    RETURN temp;
    

结果如下:

╒══════════════════════════════════════╕
│temp                                  │
╞══════════════════════════════════════╡
│{values: [4, 3, 3], ids: [a, e, c, d]}│
└──────────────────────────────────────┘