Python 大型JSON文件上的JMESPath过滤器/MultiSelect

Python 大型JSON文件上的JMESPath过滤器/MultiSelect,python,jmespath,Python,Jmespath,Datasource是一个JUniter路由器路由表,输出为json(>3 GB json文件)。我最后想要的是能够循环一系列前缀,并将前缀作为路径组合 #/usr/bin/env python 导入json 从jmespath导入搜索 jsonData=“”{ “路线信息”:[ { “路线表”:[ { “rt”:[ { “rt目的地”:[ { “数据”:“2001:db8:1::/48” } ], “rt条目”:[ { “作为路径”:[ { “数据”:“645116551 I” } ] } ]

Datasource是一个JUniter路由器路由表,输出为json(>3 GB json文件)。我最后想要的是能够循环一系列前缀,并将前缀作为路径组合

#/usr/bin/env python
导入json
从jmespath导入搜索
jsonData=“”{
“路线信息”:[
{
“路线表”:[
{
“rt”:[
{
“rt目的地”:[
{
“数据”:“2001:db8:1::/48”
}
],
“rt条目”:[
{
“作为路径”:[
{
“数据”:“645116551 I”
}
]
}
]
},
{
“rt目的地”:[
{
“数据”:“2001:db8:2::/48”
}
],
“rt条目”:[
{
“作为路径”:[
{
“数据”:“65536 64496 I”
}
]
}
]
}
]
}
]
}
]
}"""
data=json.load(jsonData)
查询=““路由信息”[]”。“路由表”[].rt[].{\“目的地\:\“rt目的地\”,路径:\“rt条目\”}”
输出=搜索(查询、数据)
打印(输出)
上述
查询
的结果是:

[{'destination': [{'data': '2001:db8:1::/48'}], 'path': [{'as-path': [{'data': '64511 65551 I'}]}]}, {'destination': [{'data': '2001:db8:2::/48'}], 'path': [{'as-path': [{'data': '65536 64496 I'}]}]}]
[{'destination': [{'data': '2001:db8:1::/48'}], 'path': None}, {'destination': [{'data': '2001:db8:2::/48'}], 'path': None}]
看来这条路走对了。但是我想要前缀:as path组合,所以我想去掉“data:”和“as path.data”部分(在实际的json文件中,这个级别上有更多的对象,我在这里尝试去掉它们)

和/或

query='"route-information"[]."route-table"[].rt[].{\"destination\": \"rt-destination\", path: \"rt-entry\".\"as-path\".data}'
结果:

[{'destination': [{'data': '2001:db8:1::/48'}], 'path': [{'as-path': [{'data': '64511 65551 I'}]}]}, {'destination': [{'data': '2001:db8:2::/48'}], 'path': [{'as-path': [{'data': '65536 64496 I'}]}]}]
[{'destination': [{'data': '2001:db8:1::/48'}], 'path': None}, {'destination': [{'data': '2001:db8:2::/48'}], 'path': None}]
知道为什么“没有”和/或如何继续吗

另一个想法是过滤:

query='"route-information"[]."route-table"[].rt[?"rt-destination".data==`2001:db8:2::/48`]'
然后继续往下走,找到as路径。但是查询结果是
[[]]
其中

query='"route-information"[]."route-table"[].rt[?"rt-destination".data=="2001:db8:2::/48"]'
导致

[[{'rt-destination': [{'data': '2001:db8:1::/48'}], 'rt-entry': [{'as-path': [{'data': '64511 65551 I'}]}]}, {'rt-destination': [{'data': '2001:db8:2::/48'}], 'rt-entry': [{'as-path': [{'data': '65536 64496 I'}]}]}]]

因此根本不需要过滤。

如果您的目标是获得一组如下所示的数据:

[
{
“目的地”:“2001:db8:1::/48”,
“路径”:“64511 65551 I”
},
{
“目的地”:“2001:db8:2::/48”,
“路径”:“65536 64496 I”
}
]
只需通过以下查询即可实现:

路由信息[]。路由表[]。rt[.{目的地:rt目的地[0]。数据,路径:rt条目[0]。作为路径[0]。数据}

但我怀疑,根据您在
rt destination
rt entry
as path
下的列表,此查询实际上可能会使您丢失一些数据

下面是一个不太可能让您丢失数据的示例,但它正在
路径下创建一个列表,因此生成的JSON如下所示:

[
{
“目的地”:[
“2001:db8:1::/48”
],
“路径”:[
“645116551 I”
]
},
{
“目的地”:[
“2001:db8:2::/48”
],
“路径”:[
“65536 64496 I”
]
}
]
查询是:

路由信息[]。路由表[]。rt[.{目的地:rt目的地[*]。数据,路径:rt条目[*]。作为路径[*]。数据|[]}
此查询使用展平运算符
|
,下面的示例对此进行了说明


下面是一个脚本,演示了这一点:

导入jmespath
数据={
“路线信息”:[
{
“路线表”:[
{
“rt”:[
{
“rt目的地”:[
{
“数据”:“2001:db8:1::/48”
}
],
“rt条目”:[
{
“作为路径”:[
{
“数据”:“645116551 I”
}
]
}
]
},
{
“rt目的地”:[
{
“数据”:“2001:db8:2::/48”
}
],
“rt条目”:[
{
“作为路径”:[
{
“数据”:“65536 64496 I”
}
]
}
]
}
]
}
]
}
]
}
查询=[
““路由信息”[]”。“路由表”[].rt[].{destination:“rt destination”[0]。数据,路径:“rt entry”[0]”。“作为路径”[0]。数据}”,
““路由信息”[]”。“路由表”[].rt[].{目的地:“rt目的地”[*]。数据,路径:“rt条目”[*]”。“作为路径”[*].data |[]}”
]
打印(jmespath.search(查询[0],数据))
打印(“-------------------------------”)
打印(jmespath.search(查询[1],数据))
印刷品(手工打磨):

[
{
“目的地”:“2001:db8:1::/48”,
“路径”:“64511 65551 I”
},
{
“目的地”:“2001:db8:2::/48”,
“路径”:“65536 64496 I”
}
]
---------------------------
[
{
“目的地”:[
“2001:db8:1::/48”
],
“路径”:[
“645116551 I”
]
},
{
“目的地”:[
“2001:db8:2::/48”
],
“路径”:[
“65536 64496 I”
]
}
]

如果您的目标是获得一组如下所示的数据:

[
{
“目的地”:“2001:db8:1::/48”,
“路径”:“64511 65551 I”
},
{
“目的地”:“2001:db8:2::/48”,
“路径”:“65536 64496 I”
}
]
只需通过以下查询即可实现:

路由信息[]。路由表[]。rt[.{目的地:rt目的地[0]。数据,路径:rt条目[0]。作为路径[0]。数据}

但我怀疑,根据您在
rt destination
rt entry
as path
下的列表,此查询实际上可能会使您丢失一些数据

下面是一个不太可能让您丢失数据的示例,但它正在
路径下创建一个列表,因此生成的JSON如下所示:

[
{
“目的地”:[
“2001:db8:1::/48”
],
“路径”:[
“645116551 I”
]
},
{
“目的地”:[
“2001:db8:2::/4