将两个Cypher语句的输出与聚合相结合

时间:2016-11-18 01:52:44

标签: neo4j cypher

我有以下单独的密码查询:

Q1: START m=node(30) MATCH (m)-[d:define]->(n) where d.start=4 RETURN n.name,COUNT(d) as count
Q2: START m=node(30) MATCH (m)-[d:define]->(n) where d.start=5 RETURN n.name,COUNT(d) as count

返回以下示例结果:

来自Q1:

a | 2
b | 1
c | 4
d | 3

从第二季度开始:

a | 1
b | 1
c | 4
e | 2

我可以离线处理结果并生成组合计数,但是我可以将上面的两个密码查询组合起来,以便从d.start 4和5中获得以下合并计数吗?

a | 2 | 1
b | 1 | 1
c | 4 | 4
d | 3 | 0
e | 0 | 2

到目前为止:我怎样才能继续将名称和计数(d)继续到下一阶段?

START m=node(30) 
MATCH (m)-[d:define]->(n) 
where d.start=4
WITH m, COLLECT (n.name, COUNT(d)) as from1
MATCH (m)-[d:define]->(n) 
where d.start=5
WITH m, COLLECT (n.name, COUNT(d)) as from2

工会对我不起作用,因为我不想将结果合并在一起。我需要将来自d.start = 4和5的计数分开,这样就更像是一个交集。

3 个答案:

答案 0 :(得分:1)

MATCH (n)
WHERE ID(n) = 30
MATCH (m)-[d:define]->(n) 
where d.start=4
WITH m, COLLECT([n.name, COUNT(c)]) as from1
MATCH (m)-[d:define]->(n) 
where d.start=5
WITH m, from1 + COLLECT([n.name, COUNT(c)]) as from2
UNWIND from2 AS row
WITH row[0] AS name, row[1] AS ct
RETURN name, SUM(ct)

虽然我不完全确定这是否会返回您期望的计数,因为您首先找到n,然后转而m转发,以便(m)-[d]->(n)路径将匹配根本不同的模式。不过,你正走在正确的轨道上;只需继续向集合添加内容,直到您获得所有结果行,然后展开一个大集合并执行聚合或其他分析。

答案 1 :(得分:1)

此查询应该执行您想要的操作:

MATCH (m)-[d:define]->(n)
WHERE ID(m) = 30 AND d.start IN [4, 5]
RETURN n.name AS name, REDUCE(c = [0, 0], x IN COLLECT(d.start) |
  CASE WHEN x = 4 THEN [c[0]+1, c[1]] ELSE [c[0], c[1]+1] END) AS counts
ORDER BY name;

您可以先创建样本数据来测试它:

CREATE (m:Foo), (a:Foo {name: 'a'}), (b:Foo {name: 'b'}), (c:Foo {name: 'c'}), (d:Foo {name: 'd'}), (e:Foo {name: 'e'}),
  (m)-[:define {start:4}]->(a),
  (m)-[:define {start:4}]->(a),
  (m)-[:define {start:4}]->(b),
  (m)-[:define {start:4}]->(c),
  (m)-[:define {start:4}]->(c),
  (m)-[:define {start:4}]->(c),
  (m)-[:define {start:4}]->(c),
  (m)-[:define {start:4}]->(d),
  (m)-[:define {start:4}]->(d),
  (m)-[:define {start:4}]->(d),
  (m)-[:define {start:5}]->(a),
  (m)-[:define {start:5}]->(b),
  (m)-[:define {start:5}]->(c),
  (m)-[:define {start:5}]->(c),
  (m)-[:define {start:5}]->(c),
  (m)-[:define {start:5}]->(c),
  (m)-[:define {start:5}]->(e),
  (m)-[:define {start:5}]->(e);

使用上述数据(并假设查询对ID使用了正确的m),查询返回:

+---------------+
| name | counts |
+---------------+
| "a"  | [2,1]  |
| "b"  | [1,1]  |
| "c"  | [4,4]  |
| "d"  | [3,0]  |
| "e"  | [0,2]  |
+---------------+

答案 2 :(得分:0)

我相信你可以抛弃COLLECT而只能使用COUNT

示例数据集:

CREATE
  (m {name: 1}),
  (m)-[:define {start: 4}]->({name: 2}),
  (m)-[:define {start: 4}]->({name: 3}),
  (m)-[:define {start: 5}]->({name: 4})

查询:

MATCH (m)-[d:define]->()
WHERE d.start=4 
WITH m, COUNT(d) as from1
MATCH (m)-[d:define]->()
WHERE d.start=5
RETURN m.name, from1, COUNT(d) as from2

结果:

╒══════╤═════╤═════╕
│m.name│from1│from2│
╞══════╪═════╪═════╡
│1     │2    │1    │
└──────┴─────┴─────┘