我有以下json数据:
{"results":
{"xxxxxx":{"id":"as23","status":1,"res":"xsd"},
{"xxxxxx":{"id":"fds34","status":2,"res":"dox"},
{"xxxxxx":{"id":"as23","status":1,"res":"kog"},
{"xxxxxx":{"id":"dgs5","status":2,"res":"dox"},
{"xxxxxx":{"id":"as23","status":2,"res":"dox"},
{"xxxxxx":{"id":"as23","status":1,"res":"dox"}
清单很长,但你明白了。我想要的是查找每个包含idas23
的对象,并计算其中有多少对象的状态为1
。
所以,我在HomeAssistant中使用这个作为休息传感器,我的过滤器表达式如下:
{{ value_json.results|selectattr("id", "==", "as23")|selectattr("status", "eq", 1)|list|length }}
我的问题是:我不知道xxxxxx
的值是什么,它们可能不同,并且仍然包含idas23
如何实现这一点?
假设JSON的正确版本为:
{
"results":[
{
"xxxxxx":{
"id":"as23",
"status":1,
"res":"xsd"
}
},
{
"xxxxxx":{
"id":"fds34",
"status":2,
"res":"dox"
}
},
{
"xxxxxx":{
"id":"as23",
"status":1,
"res":"kog"
}
},
{
"xxxxxx":{
"id":"dgs5",
"status":2,
"res":"dox"
}
},
{
"xxxxxx":{
"id":"as23",
"status":2,
"res":"dox"
}
},
{
"xxxxxx":{
"id":"as23",
"status":1,
"res":"dox"
}
}
]
}
借助过滤器json_query
和JMESPath查询语言,可以很容易地实现您的需求,它们可以帮助您在属性上实现通配符。
给定调试任务:
- debug:
var: >-
value_json | json_query(
'length(results[].*[] | [?id == `as23` && status == `1`])'
)
这将产生预期的:
ok: [localhost] =>
? |-
value_json | json_query(
'length(results[].*[] | [?id == `as23` && status == `1`])'
)
: '3'
根据@β.εηιτ.βε的答案,这可以在没有json_query
的情况下实现(如果你不想/不能使用pip install jmespath
(,只使用核心函数。
使用与@βεηιτ.βε的答案相同的假设正确json结构,以下任务:
- debug:
msg: "{{
value_json.results |
map('dict2items') |
map('map', attribute='value') |
flatten |
selectattr('id', '==', 'as23') |
selectattr('status', '==', 1)
}}"
提供:
TASK [debug] ***************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": [
{
"id": "as23",
"res": "xsd",
"status": 1
},
{
"id": "as23",
"res": "kog",
"status": 1
},
{
"id": "as23",
"res": "dox",
"status": 1
}
]
}