如何使用 json_query 过滤器提取所有等于某个值的项目

how to use json_query filter to extract all items equals to a value

这是我的 json 输出:

{
"kind": [
    {
        "inventory": "",
        "inventory_sources": "",
        "job_templates": "",
        "workflow_job_templates": "104"
    },
    {
        "inventory": "",
        "inventory_sources": "",
        "job_templates": "114",
        "workflow_job_templates": ""
    },
    {
        "inventory": "24",
        "inventory_sources": "",
        "job_templates": "",
        "workflow_job_templates": ""
    },
    {
        "inventory": "",
        "inventory_sources": "108",
        "job_templates": "",
        "workflow_job_templates": ""
    }
]

}

我想显示所有包含特定值的项目名称。 例如,我想显示包含“104”的项目名称是 'workflow_job_templates'

我测试了一些语法但没有成功:

    - debug: 
      msg: "104 is {{kind|json_query(query)}}"
      vars:
        query: "[?*==`104`].workflow_job_templates"

我知道这是一种错误的做法,但有人可以告诉我他会怎么做吗?

(更新)

下面的任务

    - debug:
        msg: "{{ item }} {{ kind|
                            map('dict2items')|
                            map('json_query', query)|
                            flatten }}"
      loop: [104, 114, 108, 24]
      vars:
        query: "[?to_string(value) == to_string('{{ item }}')].key"

给予

  msg: 104 ['workflow_job_templates']
  msg: 114 ['job_templates']
  msg: 108 ['inventory_sources']
  msg: 24 ['inventory']

(备案。蛮力法)

创建唯一的键列表

    - set_fact:
        my_keys: "{{ my_keys|default([]) + item.keys()|list }}"
      loop: "{{ kind }}"
    - set_fact:
        my_keys: "{{ my_keys|unique }}"

给予

  my_keys:
  - inventory
  - inventory_sources
  - job_templates
  - workflow_job_templates

创建包含所有值的字典

    - set_fact:
        my_dict: "{{ my_dict|default({})|combine({item: values}) }}"
      loop: "{{ my_keys }}"
      vars:
        query: "[].{{ item }}"
        values: "{{ kind|json_query(query) }}"

给予

  my_dict:
    inventory:
    - ''
    - ''
    - '24'
    - ''
    inventory_sources:
    - ''
    - ''
    - ''
    - '108'
    job_templates:
    - ''
    - '114'
    - ''
    - ''
    workflow_job_templates:
    - '104'
    - ''
    - ''
    - ''

然后查字典。例如

    - debug:
        msg: "{{ item }} {{ my_dict|dict2items|json_query(query) }}"
      loop: [104, 114, 108, 24]
      vars:
        query: "[?value[?contains(@, '{{ item }}')]].key"

给予

  msg: 104 ['workflow_job_templates']
  msg: 114 ['job_templates']
  msg: 108 ['inventory_sources']
  msg: 24 ['inventory']

json_query 可能是您的解决方案的方程式的一部分,但此处确实不需要。

下面一段代码的解释:

  • 对列表中的每个元素应用 dict2items 过滤器。这会将每个映射转换为 {key: "key", value: "value"}
  • 的列表
  • 展平给定的列表,以便我们将所有这些元素放在一个顶层
  • Select 个元素只有“104”的值
  • 提取列表中每个元素的 key 属性
  • 使该列表唯一并对其进行排序。
    - name: Display all element having a value of 104
      debug:
        msg: "{{ kind | map('dict2items') | flatten | selectattr('value', '==', '104') | map(attribute='key') | unique | sort }}"

请注意,如果相同的键名与不同的值但其中一个是 '104.根据您的上述数据,结果是:

TASK [Display all element having a value of 104] ***************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        "workflow_job_templates"
    ]
}

如果你真的只想使用 json_query()

---
- name: PLAYBOOK Filtering
  hosts: localhost # run locally
  
  tasks:
  - name: Create json
    set_fact:
      kind: '{{ lookup("file", "kind.json") }}'

  - name: check the var was created properly
    debug:
      var: kind 

  - name: output the element that matches 104
    debug: 
      msg: "{{ kind | json_query(\"kind[?workflow_job_templates=='104'].workflow_job_templates\") }}"

  - name: 
    set_fact: 
      output: "{{ kind | json_query(\"kind[?workflow_job_templates=='104'].workflow_job_templates\") }}"

输出

TASK [output the element that matches 104] *************************************************************************************************************
ok: [localhost] => {
    "msg": [
        "104"
    ]
}

带有 json_query 的 selectattr 的正确选择是:

    - debug:
        msg: "{{ kind | map('dict2items') | flatten | json_query(query)}}"
      vars:
        - query: "[?value == `\"104\"`].key"