过滤节点或关系属性时如何匹配Neo4j节点或关系计数

时间:2019-04-26 22:30:05

标签: neo4j cypher

我有一张图:

CREATE (c1:Contract { id: "V-9087-4321" }),
       (c2:Contract { id: "V-8046-2304" }),
       (p:Partner {id: "C-4837-4536"}),
       (p)-[:POLICY_HOLER]->(c1),
       (p)-[:POLICY_HOLER]->(c2)

MATCH (p:Partner) WHERE p.id = "C-4837-4536"
CREATE (c:Claim { id: "ef70", date: "2019-04-27" }),
       (p)-[:CLAIMANT {on: "2019-04-27"}]->(c)

MATCH (p:Partner) WHERE p.id = "C-4837-4536"
CREATE (c:Claim { id: "ab90", date: "2019-04-28" }),
       (p)-[:CLAIMANT {on: "2019-04-28"}]->(c)

我想查找所有在4月1日之后提出一项以上要求的合作伙伴:

我已经尝试过了:

MATCH (claim:Claim)<-[r:CLAIMANT]-(p:Partner)
WITH count(r) as cnt, p, claim
WHERE cnt > 1 AND claim.date > '2019-04-01'
RETURN cnt, p.id

这是行不通的,因为(如果我删除了where子句),它将返回两个声明,每个声明都带有cnt=1,而不是实际对其进行汇总。我尝试根据claim.dater.on进行选择。

如何用Cypher做到这一点?

2 个答案:

答案 0 :(得分:1)

neo4j aggregating functions(如COUNT())在与“分组关键字”相同的WITHRETURN子句中使用非聚合术语。

在您示例的WITH子句中,分组键是pclaim,因此COUNT()函数正在计算每个关键字之间的r关系的数量不同的pclaim对(因此计数始终为1)。实际上,您真正想要的是每个r的{​​{1}}关系的数量。

假设每个p节点都有一个唯一的Partner,则可以使用以下简化查询找到在4月1日之后拥有多个索赔的所有合作伙伴:

id

如果您还想返回每个匹配伙伴的所有索赔清单:

MATCH (claim:Claim)<-[:CLAIMANT]-(p:Partner)
WHERE claim.date > '2019-04-01'
RETURN COUNT(claim) AS cnt, p.id

此外,为了加快搜索速度,您应该在MATCH (claim:Claim)<-[:CLAIMANT]-(p:Partner) WHERE claim.date > '2019-04-01' RETURN COUNT(claim) AS cnt, COLLECT(claim) AS claims, p.id 上创建indexuniqueness constraint

答案 1 :(得分:1)

@cybersam 很好地解释了聚合函数。我建议查看他们的答案以了解聚合函数如何工作。但是他们的查询不是根据计数过滤声明。

您可以使用以下查询查找在4月1日之后拥有一个以上主张的所有合作伙伴:

MATCH (claim:Claim)<-[r:CLAIMANT]-(p:Partner)
WHERE claim.date > '2019-04-01'
WITH count(r) as cnt, p 
WHERE cnt > 1
RETURN cnt, p.id