NEO4J密码查询:多个聚合
样本数据 示例查询:在本文末尾 目标:搜索类似于“谁确切知道2名客户并在1家公司工作”NEO4J密码查询:多个聚合,neo4j,cypher,Neo4j,Cypher,样本数据 示例查询:在本文末尾 目标:搜索类似于“谁确切知道2名客户并在1家公司工作” 步骤1:我刚刚打印了连接的客户和公司的数量,到目前为止一切正常 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, know
步骤1:我刚刚打印了连接的客户和公司的数量,到目前为止一切正常
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
步骤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
结果>α2 | 1
步骤3:现在我还需要一些Cust和Comp上的过滤器,将a和b添加到WITH子句中
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
轰!一切都是1,1
看起来聚合与with子句中的多个变量混淆了,因此开始添加multiple with子句并展开,但我无法获取它的查询
样本数据创建
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)
正如stdob所说,聚合工作正常。Cypher中的聚合使用所有非聚合变量作为分组键,分组键为聚合提供上下文
在步骤2查询中,您有:
WITH from, count(DISTINCT a) as knows, count(DISTINCT b) as works
knows
和works
都是使用count()
进行聚合的,因此from
是分组键…计数与来自节点的每个有关
在步骤3查询中,您有
WITH from, count(DISTINCT a) as knows, count(DISTINCT b) as works, a, b
因此,from
,a
和b
是分组键。。。因此,对于
中的每一行、单个a
和单个b
节点(注意,这是每个a
和b
节点连接到
中的节点的叉积),您将得到不同的a
节点和b
节点的计数,它们总是1
获得您想要的答案的更好方法(我不能肯定地说,因为您没有在查询中指定您真正想要对A
和b
做什么,您在返回中没有使用它们)是从from节点获取关系类型的程度,然后收集连接的节点(或者使用模式理解为您收集它们)
例如:
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
不清楚第三个查询想要得到什么结果。查询本身工作正常:当您同时使用变量并对其进行聚合时,您将从逻辑上收到一个结果。一个进行聚合但同时返回所有变量的查询。我想要结果的路径变量,并且至少要应用筛选器2个连接等。非常感谢,我尝试过了,您的查询效果很好,但我有一个问题。当我添加path变量时,我的计数会出错,比如匹配p1=((from:Cust--(a:Cust))与from,count(a)如所知,p1匹配p2=((from--(b:Comp))与from,knows,count(b)作为工作,P1,P2返回标题,知道,工作,P1,P2,如果我需要路径,我应该怎么做?这是因为聚合的上下文现在必须考虑路径。在英语中,你的第一个翻译成:给我这个代码< <代码> > < <代码>节点> < /Cord>节点和这个特定路径<代码> P1
。每行的特定路径将只有一个a
节点,因此您的计数将始终为1。您需要将聚合上下文保持为仅从开始的,因此如果需要路径,您必须在每个步骤中收集()(这样,它的变量就不会是分组键的一部分,您将返回到与from
相关的聚合,而不会返回其他内容)为了更好地理解,请尝试在第一次使用后返回您拥有的内容,并查看行结果:每行都有一个单独的路径。请注意哪些是聚合的,哪些不是。请记住,聚合是针对非聚合变量的。