在 Family Tree 中使用 NEO4J 获取嵌套数据

Fetching nested data with NEO4J in Family Tree

首先,我是 NEO4J 和 CYPHER 的新手。所以我在这里和那里转来转去想办法得到我想要的结果。

下面是我的图表。假设这是一个简单的家谱。

我想出了这个简单的密码查询来获取节点的直接后代

MATCH (p:Person {username: "SETHLORDM"})<-[r:CHILD_OF]-(p2) 
RETURN {current: p, children: collect(p2)}

结果的文字版如下

上面是可以的,但是如果用NEO4J可以的话,我想得到如下的文本结果。

[
  {
    "username": "SETHLORDM",
    "location": "NO_LOCATION",
    "children": [
      {
        "username": "TESTNODE_1",
        "location": "LEFT",
        "children": [
          {
            "username": "TESTNODE_3",
            "location": "LEFT",
            "children": []
          },
          {
            "username": "TESTNODE_4",
            "location": "RIGHT",
            "children": []
          }
        ],
      },
      {
        "username": "TESTNODE_2",
        "location": "RIGHT",
        "children": [
          {
            "username": "TESTNODE_5",
            "location": "RIGHT",
            "children": []],
          },
                    {
            "username": "TESTNODE_6",
            "location": "RIGHT",
            "children": []],
          }
        ],
      }
    ],
  }
]

如有任何帮助,我们将不胜感激。谢谢

一种方法是使用 apoc.convert.toTree(使用插件 apoc)。 这可以创建您正在寻找的树结构。但是,由于您的树是 bottom-up,结果将是相同的,这意味着每个节点都将指向其父节点。如果你想得到你想要的结果,使用这种方法,你将不得不改变你的关系。

例如,使用这个数据:

MERGE (a:Person{key: 1, username: "SETHLORDM"})
MERGE (b:Person{key: 2})
MERGE (c:Person{key: 3})
MERGE (d:Person{key: 4})
MERGE (e:Person{key: 5})
MERGE (f:Person{key: 6})
MERGE (g:Person{key: 7})

MERGE (b)-[:CHILD_OF]-(a) 
MERGE (c)-[:CHILD_OF]-(a) 
MERGE (d)-[:CHILD_OF]-(b)
MERGE (e)-[:CHILD_OF]-(b) 
MERGE (f)-[:CHILD_OF]-(c) 
MERGE (g)-[:CHILD_OF]-(c) 

和这个查询:

MATCH path = (p:Person {username: "SETHLORDM"})<-[r:CHILD_OF*..2]-(p2)
WITH collect(path) AS paths
CALL apoc.convert.toTree(paths)
YIELD value
RETURN value;

会给出这个结果:


  "_type": "Person",
  "child_of": [
    {
      "_type": "Person",
      "child_of": [
        {
          "_type": "Person",
          "_id": 243,
          "key": 5
        },
        {
          "_type": "Person",
          "_id": 242,
          "key": 4
        }
      ],
      "_id": 240,
      "key": 2
    },
    {
      "_type": "Person",
      "child_of": [
        {
          "_type": "Person",
          "_id": 245,
          "key": 7
        },
        {
          "_type": "Person",
          "_id": 244,
          "key": 6
        }
      ],
      "_id": 241,
      "key": 3
    }
  ],
  "_id": 239,
  "key": 1,
 
 "username": "SETHLORDM"
}

但要更改指向此的链接:

MERGE (a)-[:CHILDREN]-(b) 
MERGE (a)-[:CHILDREN]-(c) 
MERGE (b)-[:CHILDREN]-(d)
MERGE (b)-[:CHILDREN]-(e) 
MERGE (c)-[:CHILDREN]-(f) 
MERGE (c)-[:CHILDREN]-(g) 

并将查询调整为:

MATCH path = (p:Person {username: "SETHLORDM"})-[r:CHILDREN*..2]->(p2)
WITH collect(path) AS paths
CALL apoc.convert.toTree(paths)
YIELD value
RETURN value;

将提供:

{
  "_type": "Person",
  "_id": 246,
  "children": [
    {
      "_type": "Person",
      "_id": 247,
      "children": [
        {
          "_type": "Person",
          "_id": 249,
          "key": 4
        },
        {
          "_type": "Person",
          "_id": 250,
          "key": 5
        }
      ],
      "key": 2
    },
    {
      "_type": "Person",
      "_id": 248,
      "children": [
        {
          "_type": "Person",
          "_id": 252,
          "key": 7
        },
        {
          "_type": "Person",
          "_id": 251,
          "key": 6
        }
      ],
      "key": 3
    }
  ],
  "key": 1,
  "username": "SETHLORDM"
}

现在与您想要的相似...

Bonus:如果您使用的是 apoc,则可以将 MATCH 查询替换为 apoc.path.expandConfig,这对于更大的图应该更有效。