在Neo4j中查询路径,如何仅显示一次节点/边缘信息?

时间:2019-02-27 08:18:06

标签: graph 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: ...
   }, ...

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

有什么方法可以在单个查询中完成此操作吗?

2 个答案:

答案 0 :(得分:0)

您需要将路径,节点和关系收集到一个不同的列表中,然后使用apoc.map.setKey函数基于它们进行映射:

template <typename Foo>
void someClass<Foo>::increment() {
    x++;
}

答案 1 :(得分:0)

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

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

取消缠绕和重新收藏是关键

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})}