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

Jac*_*kie 2 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
Run Code Online (Sandbox Code Playgroud)

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

[ //<-- 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..}
    ]
  }
]
Run Code Online (Sandbox Code Playgroud)

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

{
    "parentNode": {...parent node stuff..},
    "links": [
      {...link stuff...},
      {...link stuff...},
    ],
    "nodes":[
      {...node stuff..}
    ]
}
Run Code Online (Sandbox Code Playgroud)

如果我尝试一个更简单的返回函数......

RETURN n as parentNode, r as links, c as nodes
Run Code Online (Sandbox Code Playgroud)

每个条目都会重复父节点。

我如何正确返回这些信息?

更新

因此,再仔细观察一下,问题似乎出在..5this 为每个节点返回 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
Run Code Online (Sandbox Code Playgroud)

会返回类似的东西

[
  {
    "nodes": {..node 2 info...},
    "sublinks":[
       [
          {.. 2 relationships (one to 1 and one to 3)...}
       ]
    ]
  },
  {
    "nodes": {..node 3 info...},
    "sublinks":[
       [
          {.. 1 relationships (one to 2)..}
       ]
    ]
  }
]
Run Code Online (Sandbox Code Playgroud)

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

Bri*_*ood 5

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

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

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

这将起作用,但对于长度为 x > 2 的任何路径,您将得到另一个 x - 2 路径,它们是该路径的子集。如果这就是您想要的,您可以返回每个结果节点以及该节点的路径:

RETURN c, path
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

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

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