首页 > 解决方案 > 在 Neo4j 中查询路径,如何只显示一次节点/边缘信息?

问题描述

如果对两个节点之间的路径进行了简单查询,例如,

MATCH (m{name:'m'}), (n{name:'n'}),
   path = (m)-[:SOME_EDGE*]->(n)
RETURN path

EDIT: 
(example result)
...
segments: [
{
   start: {
      id: 1
      labels: [lbl1, lbl2, ...],
      properties: [p1, p2, ...]
   }
   end: { ... }
   properties: { ... }

},
{
   start: {
     id: 1
     labels: [lbl1, lbl2, ...]          <--- duplicate
     properties: [p1, p2, ...]          <--- duplicate
   }   
},
...
]

生成的结果一次又一次地包含许多相同节点/边的属性/类型/ID 的重复,当路径中有循环时,情况会变得更糟。

我用谷歌搜索,发现我可以使用像

return [node in nodes(path) | id(node)] as pathNodes, 
   [r in relationships(path) | id: id(r), type: type(r)] as rels

(Example result)
   { 
      pathNodes: [1,2,3],
      rels: {id:101,type:'SOME_EDGE'},{id:102,type:'SOME_EDGE'}
   },
   {
      pathNodes: [1,2,1,3],
      rels: ...
   }, ...

但是如何将节点/关系信息(一个实体一次)添加到上面的结果中?

有没有办法在一个查询中完成这项工作?

标签: graphneo4j

解决方案


stdob--关于 UNWIND 和 COLLECT 是正确的,并且不需要使用 APOC。

几个月前我自己想出了一个解决方案,今天来到这里,所以我选择了他/她的答案,并在此处发布了没有 APOC 的解决方案。

UNWIND 和 re-COLLECT 是关键

MATCH p=(m{name:'m'})-[:'SOME_EDGE'|:'SOME_OTHER_EDGE'*1..2]->(n{name:'n'})
WITH {
  pathNodes: [node IN nodes(p) | ID(node)], 
  rels: [r IN RELATIONSHIPS(p) | {id:ID(r),ty:TYPE(r)}] 
} AS path, p
UNWIND NODES(p) AS node
RETURN {paths:COLLECT(path), nodes: COLLECT(DISTINCT{id:ID(node),name:node.name})}

推荐阅读