【问题标题】:Filtering shortest path Cypher query with a relation property restriction?使用关系属性限制过滤最短路径 Cypher 查询?
【发布时间】:2014-11-18 22:12:56
【问题描述】:

我正在尝试执行如下所示的 Cypher 查询:

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

但是,它似乎不尊重属性约束 { status: 'cleared'} ,而是简单地返回恰好通过 :IN_ESCROW 关系连接的适当匹配节点之间的所有最短路径。虽然我找不到任何文档暗示这种特殊情况,但文档确实清楚地表明应该可以对关系属性进行匹配。我是否遗漏了某些东西,或者这在 Cypher 中是不可能完成的?

目前使用的是 Neo4j 的社区版本 2.1.3。提前谢谢!

【问题讨论】:

    标签: neo4j cypher graph-databases


    【解决方案1】:

    我已经找到了我自己的询问的答案。事实证明,从我使用的 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 尽快确定一个可靠的语法来对关系进行属性匹配!

    【讨论】:

      【解决方案2】:

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

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

      ===

      此外,除此之外,您的模型似乎已损坏,因为托管是 2 个平等方之间的安排,因此似乎没有任何有序的方式来确定哪一方应该是关系的“负责人”( p1),它应该是“尾巴”(p2)。它使您更有可能创建双向的(本质上是多余的)关系。

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

      【讨论】:

      • 显然只有一个方向的两方关系,但Neo4j支持双向遍历。这个特定的查询不关心关系的方向。在我的模型中,关系的方向仅表明是哪一方发起了交换。
      • 这似乎也没有回答我原来问题的任何部分。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-11
      • 1970-01-01
      相关资源
      最近更新 更多