NEO4J Cypher查询:多个聚合

时间:2018-04-15 12:22:53

标签: neo4j cypher

样本数据

enter image description here

  

示例查询:在本文末尾

目标:搜索类似于“谁知道2个Cust并在1家公司工作”

第1步:我刚刚打印了已连接的Cust和Comp的数量,直到现在它都是好的

MATCH (from:Cust), (a:Cust), (b:Comp),
p1=((from)-[r1]-(a)), p2=((from)-[r2]-(b))
WITH from, count(DISTINCT a) as knows, count(DISTINCT b) as works 
RETURN from.title, knows, works

enter image description here

第2步:我去了并添加了WHERE子句来过滤计数,到目前为止一直很好

MATCH (from:Cust), (a:Cust), (b:Comp),
p1=((from)-[r1]-(a)), p2=((from)-[r2]-(b))
WITH from, count(DISTINCT a) as knows, count(DISTINCT b) as works 
WHERE knows=2 and works=1
RETURN from.title, knows, works

结果> Alpha | 2 | 1

第3步:现在我还想在Cust和Comp上添加一些过滤器为我的WITH子句添加a和b

MATCH (from:Cust), (a:Cust), (b:Comp),
p1=((from)-[r1]-(a)), p2=((from)-[r2]-(b))
WITH from, count(DISTINCT a) as knows, count(DISTINCT b) as works, a, b
RETURN from.title, knows, works

和BOOM!一切都是1,1

enter image description here

看起来聚合与WITH子句中的多个变量混淆,所以开始添加多个WITH子句和UNWIND,但是我无法得到它的查询。

示例数据创建

CREATE (a:Cust {title: "Alpha"})
CREATE (b:Cust {title: "Bravo"})
CREATE (c:Cust {title: "Charlie"})
CREATE (d:Cust {title: "Delta"})

create (g:Comp {title: "Google"})
create (f:Comp {title: "Facebook"})
create (s:Comp {ttile: "Stackoverflow"})

MATCH (a:Cust {title: "Alpha"}), (b:Cust {title: "Bravo"})
CREATE (a)-[:KNOWS]->(b)

MATCH (a:Cust {title: "Alpha"}), (c:Cust {title: "Charlie"})
CREATE (a)-[:KNOWS]->(c)

MATCH (d:Cust {title: "Delta"}), (c:Cust {title: "Charlie"})
CREATE (d)-[:KNOWS]->(c)

MATCH (c:Cust {title: "Charlie"}), (b:Cust {title: "Bravo"})
CREATE (c)-[:KNOWS]->(b)


MATCH (g:Comp {title: "Google"}), (s:Comp {ttile: "Stackoverflow"})
CREATE (g)-[:USES]->(s)

MATCH (f:Comp {title: "Facebook"}), (s:Comp {ttile: "Stackoverflow"})
CREATE (f)-[:USES]->(s)

MATCH (d:Cust {title: "Delta"}), (s:Comp {ttile: "Stackoverflow"})
CREATE (d)-[:WORKS_AT]->(s)

MATCH (d:Cust {title: "Delta"}), (g:Comp {title: "Google"})
CREATE (d)-[:WORKS_AT]->(g)

MATCH (a:Cust {title: "Alpha"}), (f:Comp {title: "Facebook"})
CREATE (a)-[:WORKS_AT]->(f)

MATCH (c:Cust {title: "Charlie"}), (s:Comp {ttile: "Stackoverflow"})
CREATE (c)-[:WORKS_AT]->(s)

1 个答案:

答案 0 :(得分:3)

正如stdob--所说,聚合工作正常。 Cypher中的聚合使用所有非聚合变量作为分组键,为聚合提供上下文。

在第2步查询中,您有:

WITH from, count(DISTINCT a) as knows, count(DISTINCT b) as works

knowsworks都使用count()进行汇总,因此from是分组键...计数与每个from节点有关

在第3步查询中,您有

WITH from, count(DISTINCT a) as knows, count(DISTINCT b) as works, a, b

因此,fromab是分组键...因此对于from的每一行,单个a和单b个节点(请注意,这是一个交叉产品,每个ab节点都与from相关联),您将获得不同a的计数1}}节点和b节点...总是为1。

更好的方法来获得您想要的答案(我无法肯定地说,因为您没有指定您真正想要使用ab做什么在您的查询中,您在返回时没有使用它们是从您的节点获取关系类型的度数,然后收集连接的节点(或使用模式理解将它们集合到您的集合中)。 / p>

例如:

MATCH (from:Cust)
WITH from, size((from)-[:KNOWS]-()) as knowsDeg, 
     size((from)-[:WORKS_AT]-()) as worksAtDeg, 
     [(from)-[:KNOWS]-(a:Cust) | a] as known, 
     [(from)-[:WORKS_AT]-(b:Comp) | b] as worksAt
RETURN from.title, knowsDeg, worksAtDeg, known, worksAt

此外,我应该指出您在原始查询中有交叉产品,这就是您需要在计数中使用DISTINCT的原因:

MATCH (from:Cust), (a:Cust), (b:Comp),
p1=((from)-[r1]-(a)), p2=((from)-[r2]-(b))
WITH from, count(DISTINCT a) as knows, count(DISTINCT b) as works 
RETURN from.title, knows, works

如果你没有关闭DISTINCT,那么每个的计数都是相同的,连接数的乘积:Cust节点*连接的数量:Comp节点。如果你只想要数量(并希望通过扩展而不是我的答案中的程度),你可以在没有形成交叉产品的情况下通过收集它们来匹配它们之后得到它们:

MATCH (from:Cust)--(a:Cust)
WITH from, count(a) as knows
MATCH (from)--(b:Comp)
WITH from, knows, count(b) as works
RETURN from.title as title, knows, works