Neo4j Cypher如何按resultNode分组按条件生成节点集合
Neo4j Cypher 按resultNode分组聚合关联节点实现
需求说明
当前查询返回的每行数据包含node、rootNode、resultNode三个节点字段,初始查询片段如下:
WITH node, rootNode, resultNode
需要按以下规则转换结果结构:
- 按
resultNode字段做分组聚合,处理resultNode重复的问题 - 每个分组下生成对应的节点集合,元素添加规则:
- 若
node不等于当前分组的resultNode,将node加入集合 - 若
rootNode不等于当前分组的resultNode,将rootNode加入集合
期望输出格式为每行对应一个唯一的resultNode和它的关联节点集合,示例:
- 若
resultNode1, {node1, node2, ..., rootNode1, rootNode2...} resultNode2, {node2...} resultNode3, {} resultNodeN, {nodeN..., rootNodeN} ...
实现语句
在原有查询逻辑拿到node, rootNode, resultNode三个字段后,追加以下Cypher片段即可:
带APOC插件的简洁写法
如果Neo4j环境已经安装APOC插件,可以直接用内置函数快速做列表去重:
WITH resultNode, apoc.coll.toSet( COLLECT(CASE WHEN node <> resultNode THEN node END) + COLLECT(CASE WHEN rootNode <> resultNode THEN rootNode END) ) AS relatedNodes RETURN resultNode, relatedNodes
无APOC的原生写法
如果没有安装APOC插件,用原生Cypher语法也可以实现相同效果:
WITH resultNode, COLLECT(DISTINCT CASE WHEN node <> resultNode THEN node END) AS validNodes, COLLECT(DISTINCT CASE WHEN rootNode <> resultNode THEN rootNode END) AS validRootNodes WITH resultNode, [n IN validNodes + validRootNodes WHERE n IS NOT NULL] AS relatedNodes RETURN resultNode, relatedNodes
逻辑说明
CASE WHEN判断会过滤掉和当前resultNode相等的节点,不满足条件时返回null,COLLECT聚合时会自动忽略null值- 两个聚合列表合并后做去重处理,避免同一个节点同时作为
node和rootNode出现时重复存入集合 - 当分组下没有符合条件的节点时,
relatedNodes会返回空列表,和需求里的空集合语义完全一致
内容的提问来源于stack exchange,提问作者alexanoid
相关产品推荐
相关产品推荐

