如何用Cypher查询获取Neo4j中每种关系类型的100条数据?
解决Cypher按关系类型分组取Top100的问题
原查询中直接使用LIMIT会全局限制返回的总条数,无法实现每种关系类型单独返回100条的需求。以下是几种可行的实现方式:
方法一:使用原生LIMIT PER子句(推荐,Neo4j 4.4+)
Neo4j 4.4及以上版本支持LIMIT PER语法,可直接按指定分组字段限制每组的返回条数:
MATCH (s)-[r]->(t) WHERE type(r) IN ['LIVES_IN', 'FROM', 'STUDIES'] WITH type(r) AS type, s, t ORDER BY type -- 可选,确保分组结果稳定 LIMIT 100 PER type RETURN toString(id(s)) AS source, toString(id(t)) AS target, type
方法二:使用UNION ALL逐个查询
如果使用低版本Neo4j不支持LIMIT PER,可通过UNION ALL对每个关系类型单独查询并限制条数:
-- 查询LIVES_IN类型的前100条 MATCH (s)-[r:LIVES_IN]->(t) RETURN toString(id(s)) AS source, toString(id(t)) AS target, type(r) AS type LIMIT 100 UNION ALL -- 查询FROM类型的前100条 MATCH (s)-[r:FROM]->(t) RETURN toString(id(s)) AS source, toString(id(t)) AS target, type(r) AS type LIMIT 100 UNION ALL -- 查询STUDIES类型的前100条 MATCH (s)-[r:STUDIES]->(t) RETURN toString(id(s)) AS source, toString(id(t)) AS target, type(r) AS type LIMIT 100
这种方式逻辑直观,适合关系类型数量较少的场景。
方法三:结合APOC扩展(需安装APOC)
如果已安装Neo4j的APOC扩展库,可通过分组收集后截取每组前100条:
MATCH (s)-[r]->(t) WHERE type(r) IN ['LIVES_IN', 'FROM', 'STUDIES'] -- 按关系类型分组,收集所有相关记录 WITH type(r) AS type, collect({source: toString(id(s)), target: toString(id(t))}) AS records -- 截取每组的前100条并展开 UNWIND apoc.agg.slice(records, 0, 100) AS record RETURN record.source AS source, record.target AS target, type
这种方式适合关系类型较多的场景,无需逐个编写MATCH语句。
内容的提问来源于stack exchange,提问作者Mathew
相关产品推荐
相关产品推荐

