我有以下 Cypher 查询,它返回国家/地区代码以及每个国家/地区的配置文件数量:
MATCH (p:Profile {active: true})-[:LOCATED_IN]->(loc:Location)
OPTIONAL MATCH path1 = (loc)-[:CONTAINS*0..]->(country:Location)
WHERE country.countryCode IS NOT NULL
WITH p, loc, country, path1
ORDER BY length(path1) ASC
WITH p, loc, head(collect(country)) AS nearestCountry
OPTIONAL MATCH path2 = (reverseCountry:Location)-[:CONTAINS*0..]->(loc)
WHERE reverseCountry.countryCode IS NOT NULL AND nearestCountry IS NULL
WITH p, coalesce(nearestCountry, reverseCountry) AS finalCountry
WHERE finalCountry IS NOT NULL
RETURN finalCountry.countryCode AS countryCode, COUNT(p) AS totalCount
ORDER BY totalCount DESC
每个
Location
节点可以通过Locations
关系无限嵌套其他CONTAINS
。在这条链中,无论是在 Location
之上还是之下,都只有一个带有 Location
的 NOT NULL countryCode
节点。看来我在查询中找到了这个。但我怎样才能考虑 loc
本身是否是一个国家,这意味着它有一个 countryCode IS NOT NULL
,然后在两个方向上使用 :CONTAINS*0..
绕过这两个检查,并在最终计数中使用 loc
本身?
您可以使用包含UNION
ed非重叠查询的
CALL子查询(这显示了使用neo4j 5.24之前的语法):
MATCH (p:Profile {active: true})-[:LOCATED_IN]->(loc:Location)
CALL {
WITH loc
WITH loc
WHERE loc.countryCode IS NOT NULL
RETURN loc.countryCode AS countryCode
UNION
WITH loc
MATCH (loc)-[:CONTAINS*]->(country:Location)
WHERE loc.countryCode IS NULL AND country.countryCode IS NOT NULL
RETURN country.countryCode AS countryCode
UNION
WITH loc
MATCH (country:Location)-[:CONTAINS*]->(loc)
WHERE loc.countryCode IS NULL AND country.countryCode IS NOT NULL
RETURN country.countryCode AS countryCode
}
RETURN countryCode, COUNT(p) AS totalCount
ORDER BY totalCount DESC
从 neo4j 5.24 开始,MATCH (p:Profile {active: true})-[:LOCATED_IN]->(loc:Location)
CALL (loc) {
WITH loc
WHERE loc.countryCode IS NOT NULL
RETURN loc.countryCode AS countryCode
UNION
MATCH (loc)-[:CONTAINS*]->(country:Location)
WHERE loc.countryCode IS NULL AND country.countryCode IS NOT NULL
RETURN country.countryCode AS countryCode
UNION
MATCH (country:Location)-[:CONTAINS*]->(loc)
WHERE loc.countryCode IS NULL AND country.countryCode IS NOT NULL
RETURN country.countryCode AS countryCode
}
RETURN countryCode, COUNT(p) AS totalCount
ORDER BY totalCount DESC