You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Ansible的json_query将字典键值移至子键列表并展平

使用Ansible json_query转换字典结构

现有数据结构

seinfeld:
  - name: Jerry
    jobs:
      - comedian
    friends: 
      - name: Elaine
      - name: Kramer
  - name: George
    jobs:
      - yankees
    friends:
      - name: Jerry
      - name: Susan

目标结构

new_list:
    - main: Jerry
      name: Elaine
    - main: Jerry
      name: Kramer
    - main: George
      name: Jerry
    - main: George
      name: Susan

正确的json_query解决方案

你之前的尝试问题出在merge的上下文和操作顺序不对,以下是可以直接得到目标结果的表达式:

seinfeld[].friends[] | merge(@, {main: `parent`.name})

在Ansible中直接使用的写法:

new_list: "{{ seinfeld | json_query('[].friends[] | merge(@, {main: `parent`.name})') }}"

表达式解释

  1. seinfeld[]:遍历原列表中的每个条目
  2. friends[]:取出每个条目下的所有朋友元素,此时每个元素是{name: "XXX"}格式
  3. merge(@, {main: parent.name}):将当前朋友元素与一个新字典合并,新字典的main字段值为父条目(原seinfeld列表中的对应条目)的name值
  4. 整个表达式执行后会自动展平为一维列表,正好匹配目标结构

Ansible Playbook示例

---
- name: Transform the Seinfeld data structure
  hosts: localhost
  vars:
    seinfeld:
      - name: Jerry
        jobs:
          - comedian
        friends: 
          - name: Elaine
          - name: Kramer
      - name: George
        jobs:
          - yankees
        friends:
          - name: Jerry
          - name: Susan
  tasks:
    - name: Generate new_list using json_query
      set_fact:
        new_list: "{{ seinfeld | json_query('[].friends[] | merge(@, {main: `parent`.name})') }}"

    - name: Print the result
      debug:
        var: new_list

之前尝试失败的原因

你写的[].merge({friends: friends},{main: name}) [*].map(&merge({main: name}, @), friends)存在两个问题:

  1. 第一步merge后,后续map操作中的name已经不在当前上下文,导致main字段值为null
  2. 没有正确处理列表展平,最终结构会嵌套多层,不符合目标要求

内容的提问来源于stack exchange,提问作者Gianmarco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 06:05:06