英文:
Search for an object in json by filtering on a value within that json using jmespath
问题
{
"input": {
"user": "john",
"group": "johns_group"
},
"group_data": [
{
"name": "johns_group",
"members": ["john", "michael"]
},
{
"name": "sallys_group",
"members": ["sally", "jane"]
}
]
}
使用jmespath,您可以尝试以下表达式来检索具有指定名称的组:
group_data[?name == `input.group`]
这将检查group_data
数组中的每个对象的name
属性是否等于input.group
中指定的组名。如果找到匹配的组,它将返回该组的对象。您可以进一步扩展此表达式以检查用户是否在该组的members
列表中。
如果您的数据结构更复杂或不适用于上述表达式,请提供更多信息,以便我可以提供更具体的解决方案。
英文:
I have a json file that essentially looks like this:
{
"input": {
"user": "john",
"group": "johns_group"
},
"group_data": [
{
"name": "johns_group",
"members": ["john", "michael"]
},
{
"name": "sallys_group",
"members": ["sally", "jane"]
}
]
}
Is it possible for me to retrieve the group under group_data
with the name specified in input.group
using jmespath?
I've tried the following:
group_data[?contains(name, input.group)]
But it doesn't work. If I just put in the group name however:
group_data[?contains(name, 'johns_group')]
It does work. But I can't just hardcode the names because the group_data
, input.user
, and input.group
can all change.
If this isn't possible in pure jmespath with the way I've set it up, I have control over the structure of group_data
and can change it to be more jmespath friendly. My end goal is to be able to retrieve the group object and then return a bool if input.user
is in its members
list.
答案1
得分: 1
短答案:这是不可能的。
详细信息:
- 如果你输入 group_data,你将不再看到同一级别的其他字典。你必须将这样的引用放入一个变量中,我认为。例如,在Python中
import jmespath
import json
import yaml
with open('data.json', 'r') as myfile:
data = myfile.read()
s = json.loads(data)
result = jmespath.search(f"group_data[?name == `{s['input']['group']}`].members", s)
print(yaml.dump(result))
产生的结果(以YAML格式)
- - john
- michael
在Shell中,你可以编写一个过滤器。例如,
shell> cat filter.sh
#!/bin/sh
data=`paste -`
input_group=$(echo $data | jp -u "input.group")
group_data=$(echo $data | jp -u "group_data[?name == '$input_group'].members")
printf "$group_data"
它产生相同的结果(以JSON格式)
shell> cat data.json | ./filter.sh
[
[
"john",
"michael"
]
]
- 你说你可以改变结构。我认为在 group_data 中使用字典更适合这个用例。
shell> cat data-dict.json
{
"group_data": {
"johns_group": [
"john",
"michael"
],
"sallys_group": [
"sally",
"jane"
]
},
"input": {
"group": "johns_group",
"user": "john"
}
}
你可以在不使用 jmespath 的情况下引用该值。例如,在Python中
with open('data-dict.json', 'r') as myfile:
data = myfile.read()
s = json.loads(data)
print(yaml.dump(s))
result = s['group_data']展开收缩['group']]
print(yaml.dump(result))
产生
- john
- michael
英文:
Short answer: It is not possible.
Details:
- If you enter group_data you don't see other dictionaries at the same level anymore. You have to put such a reference into a variable, I think. For example, in Python
import jmespath
import json
import yaml
with open('data.json', 'r') as myfile:
data = myfile.read()
s = json.loads(data)
result = jmespath.search(f"group_data[?name == `{s['input']['group']}`].members", s)
print(yaml.dump(result))
gives (in YAML)
- - john
- michael
In a shell, you can write a filter. For example,
shell> cat filter.sh
#!/bin/sh
data=`paste -`
input_group=$(echo $data | jp -u "input.group")
group_data=$(echo $data | jp -u "group_data[?name == '$input_group'].members")
printf "$group_data"
which gives the same result (in JSON)
shell> cat data.json | ./filter.sh
[
[
"john",
"michael"
]
]
- You say you can change the structure. Dictionaries in group_data would serve the use-case better, I think
shell> cat data-dict.json
{
"group_data": {
"johns_group": [
"john",
"michael"
],
"sallys_group": [
"sally",
"jane"
]
},
"input": {
"group": "johns_group",
"user": "john"
}
}
You can reference the value without jmespath. For example, in Python
with open('data-dict.json', 'r') as myfile:
data = myfile.read()
s = json.loads(data)
print(yaml.dump(s))
result = s['group_data']展开收缩['group']]
print(yaml.dump(result))
gives
- john
- michael
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论