使用关系属性限制过滤最短路径Cypher查询?

时间:2014-11-18 22:12:57

标签: neo4j cypher graph-databases

我尝试执行如下的Cypher查询:

MATCH p = shortestPath((a:Party { currency: 'GBP' })-[:IN_ESCROW { status: 'cleared' }]-(b:Party { currency: 'USD' }))

但是,它似乎不尊重属性约束{status:'已清除'}而是简单地返回恰好匹配的节点之间的所有最短路径:IN_ESCROW关系。虽然我找不到暗示这个特定情况的文档,但文档确实清楚地表明应该可以匹配关系属性。我错过了什么或者在Cypher中无法做到这一点?

目前正在使用Neo4j的社区版2.1.3。提前谢谢!

2 个答案:

答案 0 :(得分:3)

我发现了自己的询问答案。事实证明,从我使用的2.1.3版本开始,shortestPath目前不支持对关系属性进行过滤。但是,有一些稍微昂贵的解决方法可用。请注意,这是比较昂贵的,因为它的性能略低于索引属性上的过滤器可能是Cypher支持的那种能力,但它并不慢。

而不是:

MATCH p = shortestPath((a:Party { currency: 'GBP' })-[:IN_ESCROW { 
    status: 'cleared' 
}]-(b:Party { currency: 'USD' }))

您可以匹配shortestPath,然后通过使用谓词来强制执行属性约束:

MATCH p = shortestPath((a:Party { currency: 'GBP' })-[r:IN_ESCROW]
    -(b:Party { currency: 'USD' }))
WHERE all(x IN r WHERE x.status = 'cleared')

这里的缺点显然是我们首先匹配所有可能的最短路径:两个匹配节点之间的IN_ESCROW关系,然后过滤以确保所有关系都包含期望的属性。就个人而言,我觉得这种行为不够直观。似乎shortestPath函数可能会先前排除所需的结果,因为它只是盲目地匹配关系类型,但在野外这个查询的工作方式正如我所需要的那样。

到目前为止,这对我的表现如预期的那样。让我们希望Neo4j能够立即为关系中的属性匹配找到一个可靠的语法!

答案 1 :(得分:2)

这似乎是您当前的型号:(p1:Party)-[:IN_ESCROW]->(p2:Party)

在第三方托管方中,您实际上是否在双方之间建立了IN_ESCROW关系?如果是这样,可能其中一个关系没有status: 'cleared',从而导致匹配。

===

另外,除了其他任何事情之外,你的模型似乎已经被打破了,因为托管是两个平等党派之间的安排,所以似乎没有任何有序的方式来确定哪一方应该是" head&#34 ;关系(p1),应该是"尾巴" (p2)。它使您更有可能在两个方向上创建(基本上是多余的)关系。

我认为这种模式会更有意义:(p1:Party)<-[:HAS_PARTY]-(e:Escrow)-[:HAS_PARTY]->(p2:Party)