【问题标题】:Combine attribute value using json_query in ansible在ansible中使用json_query组合属性值
【发布时间】:2021-03-03 22:41:56
【问题描述】:

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

{
  "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 格式,我建议您添加 to_json | from_json 表达式,如下所述:

        selected_cities: "{{ test.locations| to_json | from_json | json_query(\"[?state == 'WA'].[join('-',[name,state])][]\") }}"

使用上面的表达式将在使用值或在任何条件下消除 unicode 错误。 查看JMESPath 站点以获取有关 json_query 的更多详细信息,这对解决问题非常有帮助。

【问题讨论】:

  • 我看到无数关于如何让json_query 服从提问者意愿的问题,但我不明白对它的痴迷。 Jinja2 有 for 循环和方便的 selectattr 过滤器,它们工作得很好。
  • 嗨@mdaniel,我想要它在 json_query 中的原因是根据条件从庞大的数据集中快速访问所需的数据。我同意循环可以工作,但我对这个插件有点熟悉:-)

标签: ansible jmespath json-query


【解决方案1】:

例如

    - debug:
        msg: "{{ locations|
                 json_query('[?state == `WA`].[name,state]')|
                 map('join', '-')|list }}"

给予

  msg:
  - Seattle-WA
  - Bellevue-WA
  - Olympia-WA

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

    - debug:
        msg: "{{ _names|zip(_states)|map('join', '-')|list }}"
      vars:
        _locations: "{{ locations|selectattr('state', 'eq', 'WA')|list }}"
        _names: "{{ _locations|map(attribute='name')|list }}"
        _states: "{{ _locations|map(attribute='state')|list }}"

json_query 问题(已在 2.10 及更高版本中修复)

有 JMESPath join。很遗憾

    - debug:
        msg: "{{ locations|
                 json_query('[].join(`-`, [name,state])') }}"

失败

味精:|- json_query 过滤器插件中的 JMESPathError: 在函数 join() 中,值的类型无效:Seattle,预期之一:['array-string'],收到:“AnsibleUnicode”

to_json|from_json 解决方法

引用json_query: Add examples for starts_with and contains #72821

寄存器变量返回的数据结构需要使用to_json解析 | from_json 以获得正确的结果。修复:ansible-collections/community.general#320

    - debug:
        msg: "{{ locations|to_json|from_json|
                 json_query('[].join(`-`, [name,state])') }}"

给予

  msg:
  - Seattle-WA
  - New York-NY
  - Bellevue-WA
  - Olympia-WA

【讨论】:

  • (有JMESPath join,我也想学一下怎么用。) >愿望成真。
  • 不幸的是,它对我不起作用。 (ansible 2.9.6,python3-jmespath 0.9.4-2)。是否可以发布工作版本?
  • 哦?将尝试从我的最新版本恢复到 2.9,看看这背后是什么
  • 看起来这是 to_json | from_json 问题的案例,该问题已在 2.10 上得到修复,但会影响 2.9
【解决方案2】:

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

当你在做的时候

[?state == 'WA'].[join('-', [name, state])][]

您正在创建一个数组 [join('-', [name, state])],然后无缘无故地将其展平 []

您可以使用更短的方法找到解决方案:

[?state == `WA`].join(`-`, [name, state])

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

  1. YAML 多行字符串:How do I break a string in YAML over multiple lines?

  2. JMESPath 查询中的反引号,如文档中所述:

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

    来源:https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#selecting-json-data-json-queries


所以你最终会得到(如果你使用的是 Ansible 版本

- debug:
    msg: >-
      {{ test.locations 
           | json_query('[?state == `WA`].join(`-`, [name, state])') }}

请注意:正如@Vladimir Botka在2.10之前的版本上提出的,你会受到这个问题的影响:https://github.com/ansible/ansible/issues/27299#issuecomment-331068246,迫使你在列表中添加| to_json | from_json过滤器.


鉴于剧本:

- hosts: all
  gather_facts: yes

  tasks:
    - debug:
        msg: >-
          {{ test.locations 
              | json_query('[?state == `WA`].join(`-`, [name, state])') 
          }}
      vars:
        test:
          locations:
            - name: Seattle
              state: WA
            - name: New York
              state: NY
            - name: Bellevue
              state: WA
            - name: Olympia
              state: WA

这会产生:

[
    "Seattle-WA",
    "Bellevue-WA",
    "Olympia-WA"
]

【讨论】:

    猜你喜欢
    • 2020-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-20
    • 1970-01-01
    • 2020-05-08
    • 2023-03-25
    相关资源
    最近更新 更多