如何使用 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"
这是我的 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"