按属性筛选对象,然后使用jmespath中的键进行选择



我正试图根据子属性的值筛选jmespath中对象的属性,并希望只包括子属性设置为特定值的那些属性。

基于此示例数据:

{
"a": {
"feature": {
"enabled": true,
}
},
"b": {
},
"c": {
"feature": {
"enabled": false
}
}
}

我想得到一个具有所有属性的对象,其中启用了该功能。

{
"a": {
"feature": {
"enabled": true,
}
}
}

我想我可以使用这个jmespath查询来过滤property. enabled设置为true的对象。不幸的是,它似乎不起作用,而是返回一个空数组。

*[?feature.enabled==`true`]

CCD_ 2或CCD_ 3只返回布尔值而不返回任何上下文。

即使*[?feature.enabled==真的]可以工作,它也只是一个属性值的数组,但我也需要键(ac)。有什么办法可以在jmespath实现这一点吗?

这都是一个可靠的剧本的一部分,所以肯定会有一种方法以不同的方式实现选择(Jinja2模板或自定义插件),但我想尝试jmespath,并认为它应该能够完成这样的任务。

使用Ansible 2.5及更高版本中的dict2items过滤器,您可以使用:

- debug:
msg: "{{ dict(my_data | dict2items | json_query('[?value.feature.enabled].[key, value]')) }}"

结果:

"msg": {
"a": {
"feature": {
"enabled": true
}
}
}

抱歉,但AFAIK这在本机JMESPath中是不可能的
在jq中的to_entries等不同工具中都有用于此目的的自定义内置函数
对于jmespath.py,因此对于Ansible,存在用于实现按键操作的挂起拉请求。

更新:我已经制作了json_query过滤器的修补版本
有关其他信息,请参阅此答案。

简短回答(TL;DR)

  • 事实上,是的,这只需要原生jmespath就可以实现
  • 问题是,针对源数据集的查询将非常麻烦,因为对于这种通用jmespath查询,源数据集规范化程度较差

示例

以下针对OP中源数据的jmespath查询(太长)…

[
{
"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`]

。。。产生以下结果

[
{
"item_key": "a",
"feature_enabled": true,
"source_object": {
"feature": {
"enabled": true
}
}
}
]

这与所需的输出相同或基本相似,但我们必须弯曲大脑才能达到目的,这表明我们正试图迫使一个方桩穿过一个圆孔。

陷阱

这个jmespath查询看起来如此漫长和繁琐的原因是源数据集本身对于通用jmespath询问的规范化程度很低。

这是因为它使用对象键作为顶级排序方法,而顺序索引列表就足够了。

无论何时,如果数据集可能包含任意数量的值,则最好使用序列进行顶层排序,而不是使用对象键。

如果你发现你可以在jmespath中做一些事情,但每当你向你的"任意(非固定)长度的条目集"添加另一个"条目"时,你必须修改你的jmespath查询,你就是在与jmespath作斗争,而不是使用它。

每当您看到使用Jmespath似乎"不可能完成"的查询时,几乎可以肯定的是,您所处理的数据结构使用的对象可能更适合序列。

对象键通常意味着固定数量的属性,jmespath可以很好地处理这些属性。

即使是任意深度嵌套的对象属性也很好,只要这些对象属性没有被用作顺序枚举的替代品。

当你发现你必须创建一系列的对象来绕过一个又一个的对象时,事情才开始变得不舒服。。。这在jmespath是完全可行的,但会很痛苦。

另请参阅

  • 相关stackoverflow帖子

您可以使用:

<json_data>|[*]|[? @.feature.enabled]

最新更新