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

时间:2015-02-09 05:31:17

标签: neo4j cypher

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

对于给定数量的Id值,我想检索(b)节点,其最新时间戳连接到(a)节点。之后,我打算在最新的(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的数量很大。因此,最好在单个查询中进行,而不是多次查询。

帮助将不胜感激。

此致

的Rahul

2 个答案:

答案 0 :(得分:1)

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

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))

答案 1 :(得分:0)

也可以使用ORDER BY对所有b s'时间戳进行此操作,如下所示:

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