在 Cypher 查询中使用 WITH 进行聚合

Aggregation using WITH in Cypher query

对于以下 2 个节点:(a)-[rel]-(b) 其中 (a) 具有唯一的 属性 表示 Id,(b) 具有时间戳 属性。

对于给定数量的 Id 值,我想检索具有连接到 (a) 节点的最新时间戳的 (b) 节点。之后我打算在最新的(b)中设置一些属性。

我写的查询是这样的:

Match p=(a)-[rel]-(b) where a.Id IN ["id1","id2","id3","id4","id5"] WITH MAX(b.timestamp) as MAXT MATCH (b) where b.timestamp=MAXT SET b.prop1=value1, b.prop2=value2

但是这只返回了连接到所有 (a) 节点的所有 (b) 个节点中的一个 (b) 节点。

我尝试在 WITH 之后使用 ORDER BY 进行分组,但效果不佳:

Match p=(a)-[rel]-(b) where a.Id IN ["id1","id2","id3","id4","id5"] WITH MAX(b.timestamp) as MAXT ORDER BY a  MATCH (b) where b.timestamp=MAXT SET b.prop1=value1, b.prop2=value2

我想在单个查询中实现这一点,因为 ID 的数量很大。因此,最好在单个查询中执行而不是多个查询。

我们将不胜感激。

此致,

拉胡尔

由于您想找到每个 a 节点的最大值,因此您不能按 ORDER BYLIMIT 进行全局排序。相反,您需要使用 WITH 每个 a 的最大时间戳和 b 节点的集合。后者在下一步中被过滤为最大值(此处为 RETURN)。 head 函数仅用于 return 过滤集合的第一个元素(也就是具有最大时间戳的节点):

MATCH (a)-[rel]-(b) 
WHERE a.Id in [...]
WITH a, max(b.timestamp) as bmax, collect(b) as bs
RETURN a, head(filter(x in bs where x.timestamp=bmax))

这也可以在所有 b 的时间戳上使用 ORDER BY 来完成,如下所示:

MATCH (a)-[rel]-(b) 
WHERE a.Id in [...]
WITH a, b 
ORDER BY b.timestamp DESC
WITH a, head(collect(b)) as b
SET b.prop1=value1, b.prop2=value2