如何在Ansible中按key合并JSON数组并聚合对应字段值?
解决方案
可以通过Ansible内置过滤器或Jinja2模板逻辑实现按mount_point聚合pvs的需求,以下是具体实现方式:
1. 基础聚合(单数组场景)
假设原始数据存储在original_data变量中,使用Jinja2循环结合groupby过滤器完成聚合:
- name: 按mount_point聚合pvs列表 set_fact: aggregated_data: | {% set result = [] %} {% for key, items in original_data | groupby('mount_point') %} {% do result.append({ 'mount_point': key, 'pvs': items | map(attribute='pvs') | list }) %} {% endfor %} {{ result }} - name: 查看聚合结果 debug: var: aggregated_data
执行后输出结果与你期望的结构一致:
[ { "mount_point": "/mnt/data/", "pvs": [ "9b802bd8-16a2-4558-9049-f326e8cf84b8", "992213e8-b7de-4270-adc0-dbce7d2423a1", "c855a196-c17a-4df4-b77d-5eedfa470204" ] }, { "mount_point": "/mnt/log/", "pvs": [ "c855a196-c17a-4df4-b77d-5eedfa470204", "c855a196-c17a-4df4-b77d-5eedfa470204" ] } ]
2. 合并双数组并聚合
如果需要先合并两个独立数组(比如array1和array2)再聚合,只需在逻辑中先合并数组:
- name: 合并双数组并按mount_point聚合 set_fact: combined_aggregated: | {% set combined_array = array1 + array2 %} {% set result = [] %} {% for key, items in combined_array | groupby('mount_point') %} {% do result.append({ 'mount_point': key, 'pvs': items | map(attribute='pvs') | list }) %} {% endfor %} {{ result }}
3. 纯过滤器链式写法(无需Jinja循环)
也可以用groupby+map+combine的过滤器组合实现,无需编写循环:
- name: 用过滤器链式处理聚合 set_fact: aggregated_data: > {{ original_data | groupby('mount_point') | map('map', attribute='pvs') | map('zip', original_data | groupby('mount_point') | map('first')) | map('reverse') | map('community.general.dict', key='mount_point', value='pvs') }}
内容的提问来源于stack exchange,提问作者Mak S
相关产品推荐
相关产品推荐

