【问题标题】:How to find patterns that include other patterns in order (with Neo4j, Cypher)如何按顺序查找包含其他模式的模式(使用 Neo4j、Cypher)
【发布时间】:2016-10-06 10:19:53
【问题描述】:

我正在尝试查找包含其他子模式的模式。

我有一个包含 Stop 和 Stoptime 节点以及 4 种不同类型关系的图表:WALK_TOGET_ON_THE_BUSCONTINUEGET_OFF_THE_BUSWALK_TO 具有 distancespeed 属性。其他关系具有time 属性,我使用这些属性来计算最短路径,而不是路径的长度。 xStop 是一个物理实体:公共汽车站或火车站。 xStoptime 有车辆到相关站点的路线信息、到达和离开时间。

我正在尝试查找从出发点到目的地点的路径。我将路径分成几个模式;

start=(dep:xStop {name:'Departure'})-[:WALK_TO]->(:xStop)-[:GET_ON_THE_BUS]->(s:xStoptime)
end = (dest:xStop {name:'Destination'})<-[:WALK_TO]-(:xStop)<-[:GET_OFF_THE_BUS]-(e:xStoptime)

这使我能够过滤行程的起点和终点之间的关系。

现在,行程中间可以是直接行程或间接行程。如果是直飞的话:

direct=(:xStoptime)-[:CONTINUE*]->(:xStoptime)

问题在于间接行程:您必须转移到另一辆车。我有 2 种不同的传输模式:

t1=(:xStoptime)-[:GET_OFF_THE_BUS]->(a:xStop)-[:WALK_TO]->(b:xStop)-[:Dp]->(:xStoptime)
t2=(c:xStoptime)-[:GET_OFF_THE_BUS]->(:xStop)-[:GET_ON_THE_BUS]->(d:xStoptime) where not c.name=d.name

我想找到路径m

m=(s)-[*]->(e) 

其中 m 遵循模式:direct, zero or more transfers with t1 or t2 , direct

我不使用 Cypher 的最短路径的原因是所有关系都有属性,我想根据这些属性计算多个成本。

有人可以帮忙吗?我该如何为此编写 Cypher 查询?

【问题讨论】:

  • 你能更完整地描述你的数据模型吗?例如,DARDp 关系的目的是什么?否则这个问题很难理解。您可能还应该更改这些关系类型的名称(至少在提出这个问题时),以便更容易理解这些模式。
  • 当然。我正在编辑我的帖子以包括对关系的解释。
  • 如果您要允许任一传输模式多次重复(基本上是零、一或多于一个),那么 Cypher 不会太多帮助;它可以做单一关系类型的可变长度路径,但不能做可变长度迭代模式(目前)。
  • @cybersam 我更新了关系的名称并稍微解释了图模型。
  • @ToreEschliman 您有什么建议,比如调整图形模型或其他什么?我可以用不同的视角来解决问题。

标签: neo4j cypher


【解决方案1】:

我们的数据模型可能更适合您使用不同的数据模型。例如,这里有一个替代的(具有一些但不一定是您需要的所有属性)。

备用数据模型

(A) 在 1 和 4 站之间步行:

(:Stop {id: 1})-[:WALK {distance: 0.5, speed: 3}]->(:Stop {id: 4})

(B) 在 1 号站和 4 号站之间搭车(乘坐 9 路公交车):

(:Stop {id: 1})-[:RIDE {rte: 9, dep: 15, arr: 26}]->(:Stop {id: 4})

(C) 在 1、2 和 4 站之间“直接”乘坐(始终在路线 8 上):

(:Stop {id: 1})-[:RIDE {rte: 8, dep: 12, arr: 34}]->
  (:Stop {id: 2})-[:RIDE {rte: 8, dep: 56, arr: 88}]->(:Stop {id: 4})

(D) 在 1、2 和 4 站之间进行“换乘”(在 2 站改变路线):

(:Stop {id: 1})-[:RIDE {rte: 8, dep: 12, arr: 34}]->
  (:Stop {id: 2})-[:RIDE {rte: 4, dep: 57, arr: 89}]->(:Stop {id: 4})

(E) 1、2、3 和 4 站之间的“换乘”骑行(在 2 和 3 站之间步行):

(:Stop {id: 1})-[:RIDE {rte: 8, dep: 12, arr: 34}]->
  (:Stop {id: 2})-[:WALK {distance: 0.1, speed: 3}]->
    (:Stop {id: 3})-[:RIDE {rte: 5, dep: 66, arr: 92}]->(:Stop {id: 4})

示例

如果我们在上面创建路径 A 到 E,如下所示:

CREATE (a:Stop {id: 1}), (b:Stop {id: 2}), (c:Stop {id: 3}), (d:Stop {id: 4}),
(a)-[:WALK {distance: 0.5, speed: 3}]->(d),
(a)-[:RIDE {rte: 9, dep: 15, arr: 26}]->(d),
(a)-[:RIDE {rte: 8, dep: 12, arr: 34}]->(b),
(b)-[:RIDE {rte: 4, dep: 57, arr: 89}]->(d),
(b)-[:RIDE {rte: 8, dep: 56, arr: 88}]->(d),
(b)-[:WALK {distance: 0.1, speed: 3}]->(c)-[:RIDE {rte: 5, dep: 66, arr: 92}]->(d);

那么下面的查询可能会做你想做的事。它将返回路径 B 到 E。它的模式需要在开头有一个 RIDE 关系,然后是 0 个或多个 RIDEWALK 关系:

MATCH p=(a:Stop {id: 1})-[:RIDE]->(:Stop)-[:WALK|RIDE*0..]->(:Stop)-[:RIDE]->(b:Stop {id: 2})
RETURN p;

请注意,查询不需要实际测试转移,因为您想要“零次或多次转移”。

此外,如果您确实希望最后一个关系始终是 RIDE(与起始 RIDE 不同),您可以将查询更改为:MATCH p=(a:Stop {id: 1})-[:RIDE]-&gt;(:Stop)-[:WALK|RIDE*0..]-&gt;(:Stop)-[:RIDE]-&gt;(b:Stop {id: 4}) RETURN p;。这只会返回路径 C 到 E。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-21
    • 2016-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多