基于先前关系的Cypher匹配路径

时间:2014-04-24 11:41:16

标签: neo4j cypher

我试图对我的路径匹配模式施加限制。 我想根据之前使用过的关系的类型匹配下一个关系。

以下是简化数据库的示例:

(A)-1-(B)-2-(C)-1-(E)-2-(F)
       |           |
       3----(D)----3

查询1:

start n=node(A), m=node(F) 
match p=n-[r*]-m
return p

应该产生两个路径

(A)-1-(B)-2-(C)-1-(E)-2-(F)
(A)-1-(B)-3-(D)-3-(E)-2-(F)

但是,从节点(F)开始运行查询时:

start m=node(F),n=node(A)
match p=m-[r*]-n
return p

结果应该只是:

(F)-2-(E)-1-(C)-2-(B)-1-(A)

路径

(F)-2-(E)-3-(D)-3-(B)-1-(A)

不应该有效,因为它违反了这些约束:

  1. 来自-1型关系,你可以进入a -2-或-3-关系。
  2. 来自-2-或-3型关系,你只能进行 一个-1-关系。
  3. 这些路径有效:

    ()-1-()-2-()
    ()-1-()-3-()
    ()-2-()-1-()
    ()-3-()-1-()
    

    这些路径无效:

    ()-3-()-2-()
    ()-2-()-3-()
    

1 个答案:

答案 0 :(得分:1)

首先,对非常详细,具体,布局合理的问题进行投票。

不幸的是,我不认为你可以用Cypher做你想做的事情,我认为你需要Traversal API才能做到这一点。 Cypher是一种声明性语言;也就是说,你告诉它你想要什么,然后就可以得到它。使用遍历API是查询的必要方法;也就是说,你告诉neo4j如何遍历图表。

此处的查询对关系遍历的顺序以及构成有效路径的原因施加了约束。这没有什么不对,但我相信对遍历顺序施加约束隐含意味着你告诉cypher要遍历哪种方式,而你只是不能用cypher来做,因为它是声明性的。声明性与命令性事物的另一个常见例子是广度优先与深度优先搜索。如果你正在寻找某些节点,你不能告诉密码遍历广度优先和深度优先;你只需告诉它你想要哪些节点,然后就可以获得它们。

现在,可以将路径视为collections in cypher via the relationships() function.并且您可以使用filterreduce函数来处理各个关系。但是你的查询更难,因为你需要的代码类似于“如果路径中的第一个关系是1,那么下一个必须是2或3”。这正是您在Traversal API中使用Evaluators可以做的事情。检查界面,你可以看到如何编写自己的方法,通过Evaluator#evaluate(Path path)完全实现你所谈论的逻辑。

作为一般说明,因为声明性查询(cypher)隐藏了您的遍历细节,所以如果您可以声明性地指定您想要的内容,那么使用声明性查询更容易。但是有些情况下你必须控制遍历的顺序,为此你需要遍历。 (我有一些情况,我需要所有节点连接到其他东西,通过广度优先搜索,最大深度为3,沿着复杂的关系标准 - 我不能使用cypher)。

为了给你一个前进的方法,请检查我在遍历框架上提供的链接。也许您可以将查询描述为TraversalDescription,然后将其交给neo4j运行。