使用附加过滤器查找节点之间的最短路径

Find shortest path between nodes with additional filter

我正在尝试模拟特定日期机场之间的航班。到目前为止,我的测试图如下所示:

寻找 LTN 和 WAW 之间的最短路径是微不足道的:

MATCH (f:Airport {code: "LTN"}), (t:Airport {code: "WAW"}), 
p = shortestPath((f)-[]-(t)) RETURN p

这给了我:

但我不知道如何只获取与给定日期有关系 FLIES_ON 的航班的路径。

Link to Neo4j console

问题是使用 shortestPath 或 allShortestPaths 永远不会包含 Date 节点。

你需要做的是用日期节点过滤模式(我不知道你如何存储日期,所以我将采用 Ymd 格式:

MATCH (f:Airport {code: "LTN"}), (t:Airport {code: "WAW"})
MATCH p=(f)-[*]-(t)
WHERE ANY (r in rels(p) WHERE type(r) = 'FLIES_ON')
AND ANY (n in nodes(p) WHERE 'Date' IN labels(n) AND n.date = 20150120)
RETURN p
ORDER BY length(p)
LIMIT 1

另一种成本更低的解决方案是在匹配中包含日期并用它自己构建路径:

MATCH (n:Date {date:20150120})
MATCH (f:Airport {code:"LTN"}), (t:Airport {code:"WAW"})
MATCH p=(f)<-[*]-(n)-[*]->(t)
RETURN distinct(p)
ORDER BY length(p) 

尽管这不是我对此类数据的首选结构;在回答您的问题时,我可能会改用这种方式。获取路径,过滤路径并获取第一个按长度排序的路径。

在控制台测试中运行速度比上面建议的要快,因为查询计划更简单。

无论如何,我希望这至少能为您指明一个好的方向:)

MATCH (f:Airport { cd: "ltn" }),(t:Airport { cd: "waw" }), p =((f)-[r*]-(t))
WHERE ANY (x IN relationships(p) 
           WHERE type(x)='FLIES_ON') AND ANY (x IN nodes(p) 
                                              WHERE x.cd='130114')
RETURN p
ORDER BY length(p)
LIMIT 1

以下是我将对您给定的模型执行的操作。其他评论者的查询似乎不正确,因为他们使用 ANY() 而不是 ALL()。您明确表示您只需要路径上的 all Flight 节点附加到具有 :FLIES_ON 关系的给定 Date 节点的路径:

MATCH (LTN:Airport {code:"LTN"}),
      (WAW:Airport {code:"WAW"}), 
      p =(LTN)-[:ROUTE*]-(WAW)
WHERE ALL(x IN FILTER(x IN NODES(p) WHERE x:Flight) 
          WHERE (x)<-[:FLIES_ON]-(:Date {date:"130114"}))
WITH p ORDER BY LENGTH(p) LIMIT 1
RETURN p

http://console.neo4j.org/r/xgz84y