将 JSON 类别树转换为数据库表
Posted
技术标签:
【中文标题】将 JSON 类别树转换为数据库表【英文标题】:Convert JSON categories tree to database table 【发布时间】:2018-04-04 10:14:44 【问题描述】:假设我有一个像这样的 JSON 文件的类别树:
[
"id": "1",
"text": "engine",
"children": [
"id": "2",
"text": "exhaust",
"children": []
,
"id": "3",
"text": "cooling",
"children": [
"id": "4",
"text": "cooling fan",
"children": []
,
"id": "5",
"text": "water pump",
"children": []
]
]
,
"id": "6",
"text": "frame",
"children": [
"id": "7",
"text": "wheels",
"children": []
,
"id": "8",
"text": "brakes",
"children": [
"id": "9",
"text": "brake calipers",
"children": []
]
,
"id": "10",
"text": "cables",
"children": []
]
]
我怎样才能把它转换成这个平面表?
id parent_id text
1 NULL engine
2 1 exhaust
3 1 cooling
4 3 cooling fan
5 3 water pump
6 NULL frame
7 6 wheels
8 6 brakes
9 8 brake calipers
10 6 cables
我发现了类似的问题和倒置的问题(从表格到 JSON),但我无法用 jq 及其@tsv 过滤器弄清楚。我还注意到答案中不经常引用“扁平化”过滤器(虽然它看起来正是我需要的工具),但这可能是因为它是最近在最新版本的 jq 中引入的。
【问题讨论】:
【参考方案1】:这是另一个使用 jq 的 recurse 内置的解决方案:
["id","parent_id","text"]
, (
.[]
| recurse(.id as $p| .children[] | .parent=$p )
| [.id, .parent, .text]
)
| @tsv
样本运行(假设过滤器在filter.jq
中,样本数据在data.json
中)
$ jq -Mr -f filter.jq data.json
id parent_id text
1 engine
2 1 exhaust
3 1 cooling
4 3 cooling fan
5 3 water pump
6 frame
7 6 wheels
8 6 brakes
9 8 brake calipers
10 6 cables
Try it online!
【讨论】:
太棒了!我现在可以在 curl 之后直接使用 curl ... | jq -Mr '(.[] | recurse(.id as $p| .children[] | .parent=$p) | [.id, .parent, .text]) | @tsv'【参考方案2】:这里的关键是定义一个递归函数,像这样:
def children($parent_id):
.id as $id
| [$id, $parent_id, .text],
(.children[] | children($id)) ;
使用您的数据,过滤器:
.[]
| children("NULL")
| @tsv
产生如下所示的制表符分隔值。现在可以轻松添加标题、根据需要转换为固定宽度格式等。
1 NULL engine
2 1 exhaust
3 1 cooling
4 3 cooling fan
5 3 water pump
6 NULL frame
7 6 wheels
8 6 brakes
9 8 brake calipers
10 6 cables
【讨论】:
非常感谢您的回答!最后我选择了jq170727的应用方案,因为它使用了jq内置的递归函数。【参考方案3】:这是一个使用递归函数的解决方案:
def details($parent):
[.id, $parent, .text], # details for current node
(.id as $p | .children[] | details($p)) # details for children
;
["id","parent_id","text"] # header
, (.[] | details(null)) # details
| @tsv # convert to tsv
样本运行(假设过滤器位于filter.jq
中,样本数据位于data.json
中)
$ jq -Mr -f filter.jq data.json
id parent_id text
1 engine
2 1 exhaust
3 1 cooling
4 3 cooling fan
5 3 water pump
6 frame
7 6 wheels
8 6 brakes
9 8 brake calipers
10 6 cables
Try it online!
【讨论】:
以上是关于将 JSON 类别树转换为数据库表的主要内容,如果未能解决你的问题,请参考以下文章