我试图对我的路径匹配模式施加限制。 我想根据之前使用过的关系的类型匹配下一个关系。
以下是简化数据库的示例:
(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-()-2-()
()-1-()-3-()
()-2-()-1-()
()-3-()-1-()
这些路径无效:
()-3-()-2-()
()-2-()-3-()
答案 0 :(得分:1)
首先,对非常详细,具体,布局合理的问题进行投票。
不幸的是,我不认为你可以用Cypher做你想做的事情,我认为你需要Traversal API才能做到这一点。 Cypher是一种声明性语言;也就是说,你告诉它你想要什么,然后就可以得到它。使用遍历API是查询的必要方法;也就是说,你告诉neo4j如何遍历图表。
此处的查询对关系遍历的顺序以及构成有效路径的原因施加了约束。这没有什么不对,但我相信对遍历顺序施加约束隐含意味着你告诉cypher要遍历哪种方式,而你只是不能用cypher来做,因为它是声明性的。声明性与命令性事物的另一个常见例子是广度优先与深度优先搜索。如果你正在寻找某些节点,你不能告诉密码遍历广度优先和深度优先;你只需告诉它你想要哪些节点,然后就可以获得它们。
现在,可以将路径视为collections in cypher via the relationships()
function.并且您可以使用filter
和reduce
函数来处理各个关系。但是你的查询更难,因为你需要的代码类似于“如果路径中的第一个关系是1,那么下一个必须是2或3”。这正是您在Traversal API中使用Evaluators可以做的事情。检查界面,你可以看到如何编写自己的方法,通过Evaluator#evaluate(Path path)
完全实现你所谈论的逻辑。
作为一般说明,因为声明性查询(cypher)隐藏了您的遍历细节,所以如果您可以声明性地指定您想要的内容,那么使用声明性查询更容易。但是有些情况下你必须控制遍历的顺序,为此你需要遍历。 (我有一些情况,我需要所有节点连接到其他东西,通过广度优先搜索,最大深度为3,沿着复杂的关系标准 - 我不能使用cypher)。
为了给你一个前进的方法,请检查我在遍历框架上提供的链接。也许您可以将查询描述为TraversalDescription,然后将其交给neo4j运行。