Joh*_*ler 16 json normalization ansible jmespath
我正在尝试根据子属性的值过滤jmespath中对象的属性,并且只想包含子属性设置为特定值的那些属性.
基于此示例数据:
{
"a": {
"feature": {
"enabled": true,
}
},
"b": {
},
"c": {
"feature": {
"enabled": false
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想获得一个具有启用该功能的所有属性的对象.
{
"a": {
"feature": {
"enabled": true,
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想我可以使用这个jmespath查询来过滤property. enabled设置为true 的对象.不幸的是,它似乎不起作用而是返回一个空数组.
*[?feature.enabled==`true`]
Run Code Online (Sandbox Code Playgroud)
*.feature.enabled或者*[feature.enabled]只返回没有任何上下文的布尔值.
即使*[?feature.enabled==true ]可以工作,它也只是属性值的数组,但我还需要键(a和c).有没有办法在jmespath中实现这一点?
这是一个ansible playbook的所有部分,所以肯定会有一种方法以不同的方式实现选择(Jinja2模板或自定义插件),但我想尝试jmespath并且会推理它应该能够执行这样的任务.
抱歉,AFAIK在原生JMESPath中是不可能的.在jq
这样的不同工具中有为此目的定制的内置函数.
对于Ansible而言,存在挂起请求以实现键操作.to_entriesjmespath.py
更新:我已经修改了json_query过滤器的版本.
有关其他信息,请参阅此答案.
使用dict2itemsAnsible 2.5及更高版本中的过滤器,您可以执行以下操作:
- debug:
msg: "{{ dict(my_data | dict2items | json_query('[?value.feature.enabled].[key, value]')) }}"
Run Code Online (Sandbox Code Playgroud)
结果:
"msg": {
"a": {
"feature": {
"enabled": true
}
}
}
Run Code Online (Sandbox Code Playgroud)
以下(太长)jmespath 查询针对OP中的源数据...
[
{
"item_key": `a`
,"feature_enabled": @.a.feature.enabled
,source_object: @.a
}
,{
"item_key": `b`
,"feature_enabled": @.b.feature.enabled
,source_object: @.b
}
,{
"item_key": `c`
,"feature_enabled": @.c.feature.enabled
,source_object: @.c
}
]|[? feature_enabled == `true`]
Run Code Online (Sandbox Code Playgroud)
...产生以下结果
[
{
"item_key": "a",
"feature_enabled": true,
"source_object": {
"feature": {
"enabled": true
}
}
}
]
Run Code Online (Sandbox Code Playgroud)
这与所需的输出相同或基本相似,但事实上我们必须弯曲大脑才能到达那里,这表明我们正在尝试将方形钉子穿过圆孔。
这个 jmespath 查询看起来如此长和麻烦的原因是源数据集本身对于通用 jmespath 查询的规范化很差。
这是因为它使用对象键作为顶级排序方法,而顺序索引列表就足够了。
每当您的数据集可能包含任意数量的值时,几乎总是最好使用序列进行顶级排序规则,而不是对象键。
如果您发现可以在 jmespath 中执行某些操作,但是每当您向“任意(非固定)长度的条目集”添加另一个“条目”时,您都必须修改您的 jmespath 查询,那么您就是在与 Jmespath 作斗争,而不是使用它。
每当您看到使用 Jmespath 似乎“不可能完成”的查询时,几乎可以肯定您正在处理使用序列可能更适合的对象的数据结构。
对象键通常意味着固定数量的属性,jmespath 可以很好地处理。
即使任意深度嵌套的对象属性也可以,只要这些对象属性不被用作顺序枚举的替代品即可。
当您发现必须创建对象序列才能绕过对象对象时,事情才会开始变得不舒服……这在 jmespath 中完全可行,但会很痛苦。