如何使用Cypher返回原始5跳内相关的所有节点

时间:2015-08-03 18:15:11

标签: neo4j cypher

我有一个用户正在搜索节点,我想返回该节点,找到所有关系的集合,以及相关节点的列表。我试过这样的事......

MATCH (n)
WHERE n.uuid = <uuid>
OPTIONAL MATCH n-[r*..5]-(c)
RETURN distinct(n) as parentNode, collect(r) as links, collect(c) as nodes

然而,这并不起作用,因为链接由于某种原因在列表中作为列表返回。结果如下(使用节点模块)......

[ //<-- I don't need a list
  {
    "parentNode": {...parent node stuff..},
    "links": [
      [  //<-- This is what I mean by 2 lists
        {...link stuff...}
      ],
      [  //<-- This is what I mean by 2 lists
        {...link stuff...}
      ],
    ],
    "nodes":[
        {...node stuff..}
    ]
  }
]

我希望这看起来像......

{
    "parentNode": {...parent node stuff..},
    "links": [
      {...link stuff...},
      {...link stuff...},
    ],
    "nodes":[
      {...node stuff..}
    ]
}

如果我尝试一个稍微简单的返回功能......

RETURN n as parentNode, r as links, c as nodes

每个条目重复父节点。

如何正确返回此信息?

更新

所以看起来更多似乎问题是..5这为每个节点返回1集。

所以说节点1与节点2相关,节点2与节点3相关。现在说,我们使用..5而不是..2。查询

MATCH (n)
WHERE n.number = 1
OPTIONAL MATCH n-[r*..2]-(c)
RETURN c as nodes, collect(r) as sublinks

会返回类似

的内容
[
  {
    "nodes": {..node 2 info...},
    "sublinks":[
       [
          {.. 2 relationships (one to 1 and one to 3)...}
       ]
    ]
  },
  {
    "nodes": {..node 3 info...},
    "sublinks":[
       [
          {.. 1 relationships (one to 2)..}
       ]
    ]
  }
]

正如您所看到的,节点2和3之间的关系被抓取了2次。此外,不返回节点1。这些是我试图避免的问题类型。

2 个答案:

答案 0 :(得分:4)

您可以做几件事。如果你有一个大数据集,我建议的第一件事:  *如果您没有使用标签,请使用Neo4j内部ID查找n节点  *或者,您可以使用标签并为该标签的uuid属性创建索引,以便您可以快速找到它。

那就是说,我不认为给这样的可变长度路径添加标签通常是有意义的。对于可变长度路径,您通常希望将整个路径分配给变量,如下所示:

MATCH (n)
WHERE n.uuid = <uuid>
OPTIONAL MATCH path=(n)-[*1..5]-(c)
RETURN path

这将有效,但对于长度为x的任何路径&gt; 2您将获得另一个x - 2路径,这些路径是该路径的子集。如果这是你想要的,你可以返回每个结果节点和该节点的路径:

RETURN c, path

或者,您可能只需要表示关系的一组开始/结束节点。你可以通过一些处理得到它:

MATCH (n)
WHERE n.uuid = <uuid>
OPTIONAL MATCH path=(n)-[*1..5]-(c)
WITH rels(path) AS rels
UNWIND rels AS rel
WITH DISTINCT rel
RETURN startnode(rel), endnode(rel), type(rel)

这有助于回答您的问题吗?

编辑:将path = n ...替换为path =(n)...

答案 1 :(得分:0)

我最终分成3个单独的查询......

MATCH (n {uuid: {uuid}}) return n as node

MATCH path=(n{uuid: {uuid}})-[r*..'+hops+']-(c)
WITH rels(path) AS rels
UNWIND rels AS rel
WITH DISTINCT rel
RETURN rel

MATCH path=(n {uuid: {uuid}})-[r*..'+hops+']-(c)
WITH nodes(path) AS nodes
UNWIND nodes AS node
WITH DISTINCT node
RETURN node

这似乎允许我将客户端聚合到我需要的东西。我不会接受,因为必须有更好的方法。