导致嵌套JSON结构的Neo4j递归循环查询

eiee3dmh  于 2022-10-21  发布在  其他
关注(0)|答案(2)|浏览(292)

我正在尝试弄清楚Cypher查询,以便最终获得嵌套的JSON结构。下面我给出一个图表的例子。

MATCH (user:User {name:"User_1"})
OPTIONAL MATCH (user)-[rel*]->(subUser:User)
RETURN *

上面的查询允许我获得将所有内容转换为我想要的JSON结构所需的所有节点和关系,但这需要我在从查询数据库中获得结果后处理所有内容。要实现这一点,我需要匹配节点和关系的标识,以便获得嵌套的JSON。我想知道是否有可能直接通过构建密码查询来实现这一点。重要的是,我们不知道从USER_1开始,我们有多少级别的**“子”用户**
预期的JSON结构:

{ 
    "user": "User_1",
    "children": [
        {
            "user": "User_2",
            "children": [
                {
                    "user": "User_5",
                    "children": []
                }
            ]
        },{
            "user": "User_3",
            "children": [
                {
                    "user": "User_6",
                    "children": []
                }
            ]
        },{
            "user": "User_4",
            "children": []
        }
    ]
}

可能吗?

moiiocjp

moiiocjp1#

正如@Nimrod serok的评论中所建议的,您可以使用apoc.convert.toTree方法,它将为您提供所需的树形结构的JSON,但需要注意的是,JSON的密钥将有所不同。对于数据:

MERGE (u1:User{name: 'User1'})
MERGE (u2:User{name: 'User2'})
MERGE (u3:User{name: 'User3'})
MERGE (u4:User{name: 'User4'})
MERGE (u5:User{name: 'User5'})
MERGE (u6:User{name: 'User6'})
MERGE (u1)-[:POINTS]->(u2)-[:POINTS]->(u5)
MERGE (u1)-[:POINTS]->(u3)-[:POINTS]->(u6)
MERGE (u1)-[:POINTS]->(u4)

查询:

MATCH (user:User {name:"User1"})
OPTIONAL MATCH path = (user)-[:POINTS*]->(subUser:User)
WITH collect(path) AS paths
CALL apoc.convert.toTree(paths, true, {nodes: {User: ['name']}})
YIELD value
RETURN value

生成输出:

{
  "_type": "User",
  "name": "User1",
  "_id": 4,
  "points": [
    {
      "_type": "User",
      "name": "User3",
      "_id": 6,
      "points": [
        {
          "_type": "User",
          "name": "User6",
          "_id": 9
        }
      ]
    },
    {
      "_type": "User",
      "name": "User2",
      "_id": 5,
      "points": [
        {
          "_type": "User",
          "name": "User5",
          "_id": 8
        }
      ]
    },
    {
      "_type": "User",
      "name": "User4",
      "_id": 7
    }
  ]
}

如您所见,relationship typePOINTS取代了children,而密钥name用于用户名。可以忽略其他字段_type_id

thtygnil

thtygnil2#

对于您提出的问题,apoc.Convert.toTree()无疑是最好的答案。
如果您对文本输出感兴趣,那么ORDPATH将是另一种解决方案。ORDPATH是按层次顺序排序的连接位串。有关这方面的更多信息,请访问link。实现这一点的Neo4j用户定义函数在GitHub

相关问题