如何用jq连接存在一对多关系的用户与角色数组?
jq实现用户与角色数组的关联转换
原始数据
{ "users": [ { "id": 1, "roles": [1, 2] }, { "id": 2, "roles": [1] } ], "roles": [ { "id": 1, "desc": "Viewer" }, { "id": 2, "desc": "admin" } ] }
转换需求
将上述数据中的users数组与roles数组通过角色ID关联,生成如下结构的结果:
{ "user_roles": [ { "userId": 1, "roles": ["Viewer", "admin"] }, { "userId": 2, "roles": ["Viewer"] } ] }
解决方案
基础实现
使用以下jq命令完成转换:
jq '{user_roles: .users | map({userId: .id, roles: [.roles[] as $rid | $roles[] | select(.id == $rid).desc]})}' input.json
注:执行前需确保原始JSON数据文件名为
input.json,或替换为你的实际文件名。
命令拆解
{user_roles: ...}:构建最终输出的顶层对象,指定user_roles为结果数组的键.users | map(...):遍历users数组中的每个用户对象,对每个对象执行转换逻辑{userId: .id, roles: [...]}:为每个用户生成包含userId(映射原用户的id字段)和roles数组的对象.roles[] as $rid | $roles[] | select(.id == $rid).desc:遍历当前用户的角色ID列表,在全局roles数组中匹配对应ID的角色描述,将所有匹配到的描述收集为数组
高效实现(适合大数据量)
如果数据量较大,先将roles数组转换为ID到描述的映射表,再通过ID直接取值,可避免多次遍历角色数组,提升效率:
jq ' .roles | map({key: (.id|tostring), value: .desc}) | from_entries as $role_map | {user_roles: .users | map({userId: .id, roles: [.roles[] | $role_map[(.|tostring)]]})} ' input.json
命令拆解
.roles | map({key: (.id|tostring), value: .desc}) | from_entries as $role_map:将roles数组转换为{"1": "Viewer", "2": "admin"}格式的映射表,存储为变量$role_map.users | map(...):遍历用户数组,将每个用户的角色ID转换为字符串后,从映射表中直接获取对应的角色描述,组成roles数组
内容的提问来源于stack exchange,提问作者Kaloyan Georgiev
相关产品推荐
相关产品推荐

