在ansible中使用json_查询组合属性值

在ansible中使用json_查询组合属性值,ansible,jmespath,json-query,Ansible,Jmespath,Json Query,我想使用ansible中的json_查询将两个属性组合成一个由分隔符分隔的字符串 样本数据 { "locations": [ {"name": "Seattle", "state": "WA"}, {"name": "New York", "state": "NY"}, {"nam

我想使用ansible中的json_查询将两个属性组合成一个由分隔符分隔的字符串
样本数据

{
  "locations": [
    {"name": "Seattle", "state": "WA"},
    {"name": "New York", "state": "NY"},
    {"name": "Bellevue", "state": "WA"},
    {"name": "Olympia", "state": "WA"}
  ]
}
如上面的数据集所示,我试图过滤状态“WA”,执行的输出是:

[
    "Seattle-WA",
    "Bellevue-WA",
    "Olympia-WA"
]
到目前为止,我已经尝试过:

    - debug:
        msg: "{{ chart_list.HELM_CHARTS | json_query(\"[?state == 'WA'].{name:name,state:state}\") }}"
Output:
[
  {
    "name": "Seattle",
    "state": "WA"
  },
  {
    "name": "Bellevue",
    "state": "WA"
  },
  {
    "name": "Olympia",
    "state": "WA"
  }
]

更新: 我通过试错法得到了预期的结果,以下是我的发现:

[?state == 'WA'].[join('-',[name,state])][]
Output:
[
  "Seattle-WA",
  "Bellevue-WA",
  "Olympia-WA"
]
另外,如果您提供的输入是unicode格式,我建议您添加
到_json | from _json
表达式,如下所述:

        selected_cities: "{{ test.locations| to_json | from_json | json_query(\"[?state == 'WA'].[join('-',[name,state])][]\") }}"
使用上述表达式将消除在使用值或在任何情况下出现的unicode错误。 查看站点了解关于json_查询的更多详细信息,这对解决问题非常有帮助。

例如

-调试:
msg:“{{个位置|
json_查询('[?state==`WA`.[name,state]'))|
映射('join','-')| list}”
给予

msg:
-华盛顿州西雅图
-贝勒维瓦
-瓦州奥林匹亚

同样的结果给出了以下仅使用Jinja2过滤器的任务

-调试:
msg:{{{{u names}zip({u states){map('join','-')| list}}
变量:
_位置:{{locations}selectattr('state','eq','WA')| list}
_名称:{{{u位置}地图(属性='name')|列表}”
_状态:“{{u位置}映射(属性='state')|列表}”

json_查询问题(在2.10及更高版本中修复)

还有JMESPath。不幸的是

-调试:
msg:“{{个位置|
json_查询('[].join(`-`,[name,state]))}”
失败

味精:|- json_查询过滤器插件中的JMespatheror: 在函数join()中,值的类型无效:Seattle,应为:['array-string']之一,收到:“AnsibleUnicode”

到_json |从_json解决方案

引用

从寄存器变量返回的数据结构需要使用to_json | from_json进行解析,以获得正确的结果。修正:

-调试:
msg:{{locations | to_json | from_json|
json_查询('[].join(`-`,[name,state]))}”
给予

msg:
-华盛顿州西雅图
-纽约州纽约市
-贝勒维瓦
-瓦州奥林匹亚

只是为了一种纯粹的JMESPath方法,因为您的试错解决方案仍然有一层不必要的额外复杂性

当你在做

[?state=='WA'].[连接('-',[名称,状态]])[]
您正在创建一个数组
[join('-',[name,state])]
,然后无缘无故地将其展平

您只需使用较短的方法即可找到解决方案:

[?state==`WA`]。加入(`-`,[name,state])

还请注意,您可以使用以下方法克服JMESPath查询中引号(简单或双引号)的复杂性:

  • YAML多行字符串:

  • JMESPath查询中的反勾号,如文档中所述:

    在上面的示例中,使用反勾号引用文字可以避免转义引号并保持可读性

    资料来源:


  • 因此,您的最终结果是(如果您使用的是Ansible版本<2.10,请参见下面的注释):

    -调试:
    味精:>-
    {{test.locations
    |json_查询('[?state==`WA`].join(`-`,[name,state]))}
    
    请注意:如2.10之前版本中的所述,您将受到此问题的影响:,迫使您在列表中添加一个
    | to_json | from_json
    过滤器


    根据剧本:

    -主机:所有
    收集事实:是的
    任务:
    -调试:
    味精:>-
    {{test.locations
    |json_查询('[?state==`WA`].join(`-`,[name,state]))
    }}
    变量:
    测试:
    位置:
    -姓名:西雅图
    州:佤邦
    -姓名:纽约
    州:纽约
    -姓名:贝尔维尤
    州:佤邦
    -名称:奥林匹亚
    州:佤邦
    
    这将产生:

    [
    “华盛顿州西雅图”,
    “Bellevue WA”,
    “西澳奥林匹亚”
    ]
    
    我看到无数关于如何按照发问者的意愿进行
    json\u查询的问题,但我不理解人们对它的痴迷。Jinja2有
    for
    循环和它方便的
    selectattr
    过滤器,它们工作得很好。嗨@mdaniel,我想在json_查询中使用它的原因是根据条件从巨大的数据集中快速访问所需的数据。我同意循环可以工作,但我对这个插件有点熟悉:-)(有JMESPath join。我还想学习如何使用它。)>心想事成。不幸的是,它对我不起作用。(ansible 2.9.6,python3 jmespath 0.9.4-2)。有可能发布工作版本吗?哦?我将尝试从最新版本返回到2.9,看看这背后的原因看起来这是一个问题的案例,在2.10上得到了修复,但影响了2.9