假设我正在创建以下数据库:
节点:
City (id, is_driveable), Highway (id), Road (id), etc.
边缘:
Connected_to
城市应与另一座城市的高速公路(或道路或其他任何道路)相连,该城市可以通过相同或不同的道路等与另一座城市相连。
结果我将有City->[Connected_to]->Highway->[Connected_to]->City->...
城市可以通过多种方式连接到另一座城市(想象两条平行的高速公路)。
我想选择与具有指定ID的城市相连的所有城市,但也要排除例如道路。现在我有这个查询:
MATCH path = (city)-[:CONNECTED_WITH*]-(connected_city)
WHERE id(city) = 15 AND ALL(node IN nodes(path) WHERE NOT node:Road)
RETURN city, relationships(path) as r, connected_city
如果一个城市仅以一种方式连接到另一个城市,则该方法非常有用。当我提到两条连接相同城市的平行公路时,问题就开始了。然后此查询导致无限循环(至少我相信)。我认为它找到了从第一个城市到第二个城市的路径,然后又回到了第一个城市,依此类推。我不能限制到达目标的跃点数,因为它可以变化。
关于如何完成此操作的任何想法?
答案 0 :(得分:0)
您可以使用APOC Procedures path expanders获取所有连接的节点并解决Cypher限制,否则将导致此类查询永远旋转,但这是一个缺点。达到这种效率的方式是,仅通过一条不同的路径访问每个不同的节点一次(从而减少了查询查询所生成的路径数量,并在找到相同路径时消除了通往同一节点的多条路径),因此您不会获得到所有节点的所有可能路径,而只有一条可能的路径。
如果可以接受,那么您应该能够使用APOC路径扩展器来实现所需的功能,尤其是apoc.path.spanningTree()
(因为它会将路径返回到每个节点)或apoc.path.subgraphNodes()
(如果您只需要连接的节点,而不是它们的路径)。我们可以使用标签过滤器来确保连接节点的路径不包括:Roads,并且始终在:City节点结束。
MATCH (city)
WHERE id(city) = 15
CALL apoc.path.spanningTree(city, {labelFilter:'-Road|>City', relationshipFilter:'CONNECTED_WITH'}) YIELD path
WITH city, path
WHERE length(path) <> 0
RETURN city, relationships(path) as r, last(nodes(path)) as connected_city