在 where 子句中进行聚合的复杂查询

Complex query with agregation in where clause

假设我有一个图,其中对于 BallT 类型的每对节点 m,n 可以有一个 BallD 类型的节点 k 通过 Rel 类型的关系连接它们,也就是说,可以有多个模式那种 p=(m:BallT)-[r:Rel]-(k:BallD)-[s:Rel]-(n:BallT)。对于给定的节点 m(例如满足 m.key="whatever"),我们称 Nmn 为连接 m 和某个节点 n 的 BallD 的数量,N 为 BallD 节点的总数。对于这个给定的节点 m,我如何找到所有节点 n 使得 Nmn > N/2 并按 Nnm 对结果进行排序?我正在尝试查询:

match (D:BallD)
with count(D) as N
match (m:BallT {key:"whatever"})-[r]-(d:BallD)-[s]-(n:BallT)
with N, distinct n as n_dist, count(d) as Nmn
where Nmn >= N
return n_dist
order by Nmn

但我得到了

Invalid input 't': expected whitespace, comment, node labels, MapLiteral, a parameter, a relationship pattern

这个查询是否符合您的要求?

MATCH (D:BallD)
WITH count(D) as N
MATCH (m:BallT {key:"whatever"})--(d:BallD)--(n:BallT)
WITH N, n, count(d) as Nmn
WHERE Nmn >= N/2
RETURN n, Nmn
ORDER BY Nmn
  • 在一个值(如n)上使用聚合函数(如count)时,不需要使用DISTINCT来限定该值您正在汇总 - 这是自动为您完成的。

  • ORDER BY 参数必须引用部分返回值。

  • 此外,我更正了 WHERE 子句以使用 N/2

仅供以后参考!!我想做的是:我有一个键数组 ["k1",..,"kn"] 出现在地图 d 中。对于每个键 ki (i=1,..,n) 我想为其创建节点(如果尚未创建),计算 ki 在该映射中出现的次数以及增加 ki 出现的总数在我最终要插入数据库的所有地图中。要执行这一组创建,我执行此查询:

create (d:Map)
with d
unwind [k1,...,kn] as k0
with distinct k0 as kd0, count(k0) as c, d
merge (k:Key {key: kd0})
on create set t.count = c, t.mapCount = 1
on match set t.count = t.count + c, t.mapCount = t.mapCount + 1
create (d)-[r:Contains {count: c}]->(t)
return t

请注意,在此查询中,我注册了 ki 在表示它的节点中出现的总数以及它在某些映射 d 中的关系(包含类型)中的出现次数,该关系与两者相关(对不起,我的英语不好!呵呵)

之后,假设我想找到与键 [k1,...,kn] 共同出现的所有键 k(即,通过某些映射 d),但仅限于那些与 [k1,...,kn] 共同出现的键 k =24=] 与 ki (即 k 和 ki 与 i=1,..,n 相关的映射数大于 M),但一般不会出现 "a lot"(即, k 出现的映射一般小于 N)。在这种情况下,我执行以下查询:

unwind [k1,...,kn] as ki
match (:Key {key: ki})<-[r:Contains]-(d:Map)-[s:Contains]->(k:Key)
where k.mapCount < N
with distinct(k) as kd, count(d) as x
where x > M
return kd
order by x desc, kd.count desc
limit 5

请注意,在此查询中,我首先按 x(同时包含 ki 和 k 的地图的数量)对结果进行排序,然后按 k 的出现次数对结果进行排序,即,如果两个 k 具有相同的 x,则将计数较高的 k 放在第一位。

非常感谢你们的回复....我从来都不是 Whosebug 的频繁用户,但现在我想我会经常使用它!! :)