2016-11-28 83 views
1

考虑我有下面的图表与边权:穿越的Neo4j图形的Cypher

enter image description here

我想知道我是否可以进行遍历起始节点和以下的边缘随使用CYPHER的重量顺序。这是它应该返回(a)-4->(e)-3->(c)-3->(d)

这可能使用密码?

回答

1

您的描述稍有不当(根据你的例子),因为你不想遍历与关系越来越重,要遍历与最大重量在每一步的关系(S) 。

你不能在Cypher中以通用的方式完成它,因为结果是迭代构建的,而且你无法知道结果路径的最大长度。

在暗号,你就必须

  1. 构建所有路径
  2. 第一关系
  3. 过滤器由第二关系的加权其余的重量进行筛选(其如果存在的话)

Cypher支架的声明性质是不是真的兼容:它会很麻烦,并可能很慢。建立一个procedure或函数(在即将到来的Neo4j 3.1中)traversing最长的路径将变得容易得多,而PathExpander只返回与来自当前节点的最大权重的关系。

+0

所以基本上我不得不求助于只和最好遍历API在存储过程编写API代码为你解释[我这个问题(HTTP ://stackoverflow.com/questions/40720077/using-neo4j-traversal-api-to-perform-traversal-on-neo4j-running-on-other-machine)...? – Mahesha999

+0

我认为这是一个更好的工具,是的。 –

2

正如@FrankPavageau所述,用Java编写解决方案可能不那么麻烦,速度也更快。尽管如此,利用现有的APOC程序apoc.periodic.commit,您不必在Java中实现任何内容。

apoc.periodic.commit将重复执行Cypher查询,直到它返回值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中执行的重复执行之间,并保持最终结果)。 (在采样数据中,起始节点具有一个aid。)

    MERGE (temp:Temp) 
    SET temp = {values: [], ids: ['a']}; 
    
  2. 查询调用apoc.periodic.commit以执行所传递的Cypher支架语句的重复执行。每次执行Cypher语句时,它将从最后找到的节点(id位于temp.ids的末尾)开始,并尝试查找其关系具有最高值的下一个节点。如果最后一个节点是叶节点,则Cypher语句不返回任何内容(因为第二个MATCH将失败,中止该语句) - 这将终止该过程;否则,Cypher支架声明将追加maxtemp.values和相应的节点idtemp.ids,并返回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集合将是沿着“最大路径”的节点的ID,并且values集合将是沿相同路径的NEXT关系的values

    MATCH (temp:Temp) 
    RETURN temp; 
    

下面是结果:

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