Cypher查询求助:按'in'/'out'关系类型拆分结果列
我明白你想要的效果——按每个小时区间(通过n划分),分别统计in和out两种关系的数量与流量总和,并且把两类结果放在各自的列里展示。之前的尝试要么语法有误,要么把两类数据混在了一起,我来给你一个可行的解决方案:
推荐解决方案:使用条件聚合实现分类型统计
UNWIND range(0, 9) AS n // 注:range(0,10)会生成0-10共11个值,你原代码的[0..10]取前10个即0-9,直接写range(0,9)更清晰 MATCH (c:cluster{clusterid:'abc'})-[:in_cluster]-()-[t]-() WHERE (1525132800 + 3600 * n) <= t.time < (1525132800 + 3600 * (n + 1)) RETURN n, COUNT(CASE WHEN type(t) = 'in' THEN t END) AS in_count, COALESCE(SUM(CASE WHEN type(t) = 'in' THEN t.value END), 0)/100000000 AS in_flow, COUNT(CASE WHEN type(t) = 'out' THEN t END) AS out_count, COALESCE(SUM(CASE WHEN type(t) = 'out' THEN t.value END), 0)/100000000 AS out_flow ORDER BY n
逻辑说明
- 时间区间过滤:通过
UNWIND生成每个小时的标识n,再用WHERE子句筛选出对应时间窗口内的关系 - 条件聚合拆分数据:
COUNT(CASE...):仅当关系类型为in/out时返回关系对象,否则返回null,而COUNT会自动忽略null,最终得到对应类型的关系数量SUM(CASE...):仅累加对应类型关系的value,用COALESCE是为了避免某个区间无对应类型关系时,SUM返回null,将其转为0后再计算流量(避免除法报错)
- 结果展示:每个
n对应的行里会同时展示in和out两类统计数据,完全符合你想要的分列效果
为什么之前的方法不行?
- 第一个写法里
t:in的语法是错误的,Cypher不支持在聚合函数中直接用关系类型做过滤条件 - 第二个写法通过
UNWIND ['in','out']拆分类型,会导致每个n生成两行结果(一行in、一行out),无法将两类数据合并到同一行展示
备选方案:使用OPTIONAL MATCH分别匹配关系
如果你的场景中节点数量较少,也可以用这种更直观的写法(注意:节点较多时可能产生笛卡尔积,性能不如条件聚合):
UNWIND range(0,9) AS n MATCH (c:cluster{clusterid:'abc'})-[:in_cluster]-(node) OPTIONAL MATCH (node)-[in_rel:in]-() WHERE (1525132800 + 3600 * n) <= in_rel.time < (1525132800 + 3600 * (n + 1)) OPTIONAL MATCH (node)-[out_rel:out]-() WHERE (1525132800 + 3600 * n) <= out_rel.time < (1525132800 + 3600 * (n + 1)) RETURN n, COUNT(in_rel) AS in_count, COALESCE(SUM(in_rel.value),0)/100000000 AS in_flow, COUNT(out_rel) AS out_count, COALESCE(SUM(out_rel.value),0)/100000000 AS out_flow ORDER BY n
内容的提问来源于stack exchange,提问作者Tal Omer
相关产品推荐
相关产品推荐

