JMESPath表达式可展平对象数组,每个对象均带有嵌套的对象数组 [英] JMESPath expression to flatten array of objects, each with nested arrays of objects

查看:96
本文介绍了JMESPath表达式可展平对象数组,每个对象均带有嵌套的对象数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含数据库数组的JSON,每个数据库都有一个用户数组,例如

I have JSON containing an array of databases, each database has an array of users, e.g.

{"databases": [
  {"db": "db_a", "users": [{"name": "alice"}, {"name": "alex"}]},
  {"db": "db_b", "users": [{"name": "bob"}, {"name": "brienne"}]}
]}

我想生产一组扁平的数据库和用户,即

I would like to produce a flat array of databases and users, i.e.

[
  {"db": "db_a", "name": "alice"},
  {"db": "db_a", "name": "alex"},
  {"db": "db_b", "name": "bob"},
  {"db": "db_b", "name": "brienne"}
]

在SQL术语中,这将是笛卡尔连接或笛卡尔乘积,但是我不确定树结构中的正确术语.我到目前为止最接近的是

In SQL terms this would be a cartesian join or cartesian product, but I'm not sure of the correct term in a tree structure. The closest I've got so far is

databases[].users[]

产生

[{"name": "alice"}, {"name": "alex"}, {"name": "bob"}, {"name": "brienne"}]

databases[].{db: db, name: users[].name}

产生

[
  {"db": "db_a", "name": ["alice", "alex"]},
  {"db": "db_b", "name": ["bob", "brienne"]}
]

附录:我很高兴接受您无法使用JMESPath做到这一点,这就是原因..."作为答案. HN评论在此暗示

Addendum: I'm happy to accept "You can't do that with JMESPath, here's why ..." as an answer. An HN Comment`` hints at this

在进行迭代时无法引用父级.为什么?用于迭代的所有选项,[*]和map都将迭代项用作任何表达式的上下文.没有机会获得其他任何值

can't reference parents when doing iteration. Why? All options for iteration, [* ] and map, all use the iterated item as the context for any expression. There's no opportunity to get any other values in

推荐答案

您不能使用 just JMESPath做到这一点,因为JMESPath表达式只能引用单个作用域.当前范围是用户对象时,无法到达外部范围(数据库对象). JEP 11 将允许访问其他范围,但尚未被接受几年后.

You can't do this with just JMESPath, because JMESPath expressions can only refer to a single scope. There's no way to reach the outer scope (database objects), when the current scope is a user object. JEP 11 would allow access to other scopes, but it hasn't been accepted after several years.

在Ansible上,可以使用其他过滤器(h/t弗拉基米尔)和一些难看的东西

On Ansible it can be done with other filters (h/t Vladimir), and some ugliness

databases_users: "{{ 
    databases | subelements('users')
              | to_json | from_json
              | json_query('[*].{db: [0].db, name: [1].name}')
}}"

说明

提醒一下,我们的出发点是

Explanation

As a reminder, our starting point is

[ {"db": "db_a", "users": [{"name": "alice"}, {"name": "alex"}]},
  ...]

subelements过滤器将其转换为Python元组对列表

the subelements filter transforms this into a list of Python tuple pairs

[ ({"db": "db_a", "users": [{"name": "alice"}, {"name": "alex"}]},
   {"name": "alice"}),
  ...]

to_jsonfrom_json将元组对转换为列表(Python的JMESPath忽略元组)

to_json and from_json convert the tuple pairs to lists (JMESPath for Python ignores tuples)

[ [{"db": "db_a", "users": [{"name": "alice"}, {"name": "alex"}]},
   {"name": "alice"}],
  ...]

json_query选择所需的dbuser

[ {"db": "db_a", "name": "alice"},
  ...]

这篇关于JMESPath表达式可展平对象数组,每个对象均带有嵌套的对象数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆