Cypher 查询 - 收集连接到第三种类型节点的两种不同类型的节点
Cypher Query - Collect two separate types of nodes connected to a third type of node
首先,这是我想要的,然后我将解释我尝试过的方法。
在这个简化的示例中,我有一个包含节点 A
、B
、C
和 D
的图形。我只有 A->B
、B->C
和 B->D
这样的关系。我想将到节点 A 的每个连接聚合到一个列表中,然后将到节点 B 的每个连接聚合到两个单独的列表中:一个用于 B->C
连接,一个用于 B->D
连接。类似下面的内容。
{
'A': 'A',
'Bs': [{
'B': 'B',
'Cs': [
...
]
'Ds': [
...
]
}, ...]
}
现在针对我的特定用例。我有连接到 waypoints 的行程节点。 Waypoints 连接到机场和我所说的 POI。我想要 return 一个包含其 waypoints 列表的旅行,其中每个航路点都有两个列表:一个机场列表和一个 POI 列表。我无法成功完成此操作,也没有找到任何与此确切用例相关的示例。除了下面的查询之外,我还尝试了 foreach 循环和其他构造的许多其他变体。我认为这是我最接近的一次。在下面的查询中,B->C
等同于 HAS_AIRPORTS
关系,B->D
等同于 HAS_POI
关系。我认为我的问题归结为需要在同一级别进行多个聚合。由于 2 个聚合,我得到一些奇怪的输出,其中事情似乎在重复。抱歉,如果不清楚,我是密码查询语言术语的新手。谢谢,我很感激任何帮助。
MATCH (t:Trip {uid: $tripId})
WITH t
OPTIONAL MATCH (t)-[:HAS_WAYPOINTS]-(w {active: true})
WITH t, w
OPTIONAL MATCH (w)-[wa:HAS_AIRPORT]-(a:NeoAirport)
WITH t, w, collect(a{.*, active:wa.active}) as airports
WITH t, w {.*, airports:airports } as waypoints
OPTIONAL MATCH (w)-[wp:HAS_POI {active: true}]-(p:PointOfInterest)
WITH t, waypoints, w, collect({source:wp.source, uid:p.uid, placeId:p.placeId}) as pois
WITH t, apoc.map.setKey( waypoints, 'pointsOfInterest', pois )
WITH t, t {.*, waypoints: collect(waypoints) } as trips
OPTIONAL MATCH (t)-[tsa:HAS_START_AIRPORTS]-(sa)
WITH t, collect(sa) as sa, trips
WITH t, apoc.map.setKey( trips, 'startAirports', sa ) as trips
OPTIONAL MATCH (t)-[tea:HAS_START_AIRPORTS]-(ea)
WITH t, collect(ea) as ea, trips
WITH t, apoc.map.setKey( trips, 'endAirports', ea ) as trips
RETURN trips
有一件事会有所帮助,聚合并不是将匹配模式的结果放入列表的唯一方法。您可以改用 pattern comprehensions,这可能会简化您的查询。
此外,我将假设旅行的终点机场存在 :HAS_END_AIRPORTS 关系,我们应该使用它来获得终点机场。
MATCH (t:Trip {uid: $tripId})
OPTIONAL MATCH (t)-[:HAS_WAYPOINTS]-(w {active: true})
WITH t, w,
[(w)-[wa:HAS_AIRPORT]-(a:NeoAirport) | a {.*, active:wa.active}] as airports,
[(w)-[wp:HAS_POI {active: true}]-(p:PointOfInterest) | p {source:wp.source, .uid, .placeId}] as pointsOfInterest
WITH t, collect(w {.*, airports, pointsOfInterest}) as waypoints
WITH t, waypoints,
[(t)-[:HAS_START_AIRPORTS]-(sa) | sa] as startAirports,
[(t)-[:HAS_END_AIRPORTS]-(ea) | ea] as endAirports
RETURN t {.*, waypoints, startAirports, endAirports} as trips
首先,这是我想要的,然后我将解释我尝试过的方法。
在这个简化的示例中,我有一个包含节点 A
、B
、C
和 D
的图形。我只有 A->B
、B->C
和 B->D
这样的关系。我想将到节点 A 的每个连接聚合到一个列表中,然后将到节点 B 的每个连接聚合到两个单独的列表中:一个用于 B->C
连接,一个用于 B->D
连接。类似下面的内容。
{
'A': 'A',
'Bs': [{
'B': 'B',
'Cs': [
...
]
'Ds': [
...
]
}, ...]
}
现在针对我的特定用例。我有连接到 waypoints 的行程节点。 Waypoints 连接到机场和我所说的 POI。我想要 return 一个包含其 waypoints 列表的旅行,其中每个航路点都有两个列表:一个机场列表和一个 POI 列表。我无法成功完成此操作,也没有找到任何与此确切用例相关的示例。除了下面的查询之外,我还尝试了 foreach 循环和其他构造的许多其他变体。我认为这是我最接近的一次。在下面的查询中,B->C
等同于 HAS_AIRPORTS
关系,B->D
等同于 HAS_POI
关系。我认为我的问题归结为需要在同一级别进行多个聚合。由于 2 个聚合,我得到一些奇怪的输出,其中事情似乎在重复。抱歉,如果不清楚,我是密码查询语言术语的新手。谢谢,我很感激任何帮助。
MATCH (t:Trip {uid: $tripId})
WITH t
OPTIONAL MATCH (t)-[:HAS_WAYPOINTS]-(w {active: true})
WITH t, w
OPTIONAL MATCH (w)-[wa:HAS_AIRPORT]-(a:NeoAirport)
WITH t, w, collect(a{.*, active:wa.active}) as airports
WITH t, w {.*, airports:airports } as waypoints
OPTIONAL MATCH (w)-[wp:HAS_POI {active: true}]-(p:PointOfInterest)
WITH t, waypoints, w, collect({source:wp.source, uid:p.uid, placeId:p.placeId}) as pois
WITH t, apoc.map.setKey( waypoints, 'pointsOfInterest', pois )
WITH t, t {.*, waypoints: collect(waypoints) } as trips
OPTIONAL MATCH (t)-[tsa:HAS_START_AIRPORTS]-(sa)
WITH t, collect(sa) as sa, trips
WITH t, apoc.map.setKey( trips, 'startAirports', sa ) as trips
OPTIONAL MATCH (t)-[tea:HAS_START_AIRPORTS]-(ea)
WITH t, collect(ea) as ea, trips
WITH t, apoc.map.setKey( trips, 'endAirports', ea ) as trips
RETURN trips
有一件事会有所帮助,聚合并不是将匹配模式的结果放入列表的唯一方法。您可以改用 pattern comprehensions,这可能会简化您的查询。
此外,我将假设旅行的终点机场存在 :HAS_END_AIRPORTS 关系,我们应该使用它来获得终点机场。
MATCH (t:Trip {uid: $tripId})
OPTIONAL MATCH (t)-[:HAS_WAYPOINTS]-(w {active: true})
WITH t, w,
[(w)-[wa:HAS_AIRPORT]-(a:NeoAirport) | a {.*, active:wa.active}] as airports,
[(w)-[wp:HAS_POI {active: true}]-(p:PointOfInterest) | p {source:wp.source, .uid, .placeId}] as pointsOfInterest
WITH t, collect(w {.*, airports, pointsOfInterest}) as waypoints
WITH t, waypoints,
[(t)-[:HAS_START_AIRPORTS]-(sa) | sa] as startAirports,
[(t)-[:HAS_END_AIRPORTS]-(ea) | ea] as endAirports
RETURN t {.*, waypoints, startAirports, endAirports} as trips