首页 > 解决方案 > 如何解决jsonb中的递归嵌套树?

问题描述

所以我有一棵像这样的扁平树:

[{
    aid: "id3"
    atype: ""
    data: ["id1", "id2"]
},

{
    aid: "id1"
    atype: ""
    data: ["id3", "id2"]
},

{
    aid: "id2"
    atype: ""
    bdata: {aid: "id4", atype: "nested", data: ["id1", "id3"]}
    data: []
}]

我想收集那棵树并使用递归循环将 id 解析为数据,就像这样(比如我们从 开始"id3"):

{
    aid: "id3"
    payload: "1"
    data: [ 
    "id1":{
        aid: "id1"
        atype: ""
        data: ["id3":Null, "id2":Null]
    },
    "id2":{
            aid: "id2"
            atype: ""
            bdata: {aid: "id4", atype: "nested", data: ["id1":Null, "id3":Null]}
            data: []
    }]
}

这样我们就可以进行广度优先搜索并"value": "object with that field"在第一次进入时将某些字段解析为"value": Null

那么如何在 Postgres JSONb\ JSON中将这样的列表实现到树中呢?

我知道可以使用 PL/Python 之类的东西来做到这一点,但我没有看到一个 PL/Python 函数示例可以做这样的事情,比如不将所有 JSON 记录放入 ram 中......

{'id1': {'aid': 'id1', 'atype': '', 'data': ['id3', 'id2']},
 'id2': {'aid': 'id2',
  'atype': '',
  'bdata': {'aid': 'id4', 'atype': 'nested', 'data': ['id1', 'id3']},
  'data': []},
 'id3': {'aid': 'id3', 'atype': '', 'data': ['id1', 'id2']}}

对我来说不是真的有用 - 所以我需要一棵真正的树。

标签: jsonpostgresqltreebreadth-first-searchjsonb

解决方案


你的方法有问题。

让我们考虑跟随json。

  {
    "aid": "id3",
    "atype": "",
    "data": ["id1", "id2"]
  },

  {
    "aid": "id4",
    "atype": "",
    "data": ["id1", "id2"]
  }

在这里,id1和id2数据需要为id4再次复制,会产生大量重复数据。

取而代之的是,将您的数据转换为字典。您只需调用“id1”、“id2”等id 即可访问数据。

data_map = {}
for data in data_array:
   data_map.__setitem__(data['aid'], data)

以下将是示例输出。

{
  "id3": {
  "aid": "id3",
  "atype": "",
  "data": [
    "id1", "id2"
  ]
}

这样您就可以直接访问 id 并且在结构中没有重复项。

完整的示例代码

import json

json_data = '''
[
  {
    "aid": "id3",
    "atype": "",
    "data": ["id1", "id2"]
  },

  {
    "aid": "id1",
    "atype": "",
    "data": ["id3", "id2"]
  },

  {
    "aid": "id2",
    "atype": "",
    "bdata": {"aid": "id4", "atype": "nested", "data": ["id1", "id3"]},
    "data": []
  }
]
'''
data_array = json.loads(json_data)

data_map = {}
for data in data_array:
    data_map.__setitem__(data['aid'], data)

print(data_map)

推荐阅读