MongoDB中$mergeObjects输入类型错误及基于邮箱判断权限添加hasAccess字段失败问题
解决
$mergeObjects requires object inputs, but input is of type array报错并实现权限标记需求 我来帮你搞定这个问题!首先看你遇到的报错,核心原因是你在$map里指定的input路径不对,导致传给$mergeObjects的是数组而非单个对象。
先明确你的需求:给children0数组里每个元素的access子数组中的每个权限条目,添加hasAccess字段,标记该条目的邮箱是否匹配目标用户(比如user1@email.com)。
正确的聚合管道代码
[ { "$addFields": { "children0": { "$map": { "input": "$children0", "as": "child", "in": { "$mergeObjects": [ "$$child", { "access": { "$map": { "input": "$$child.access", "as": "accessInfo", "in": { "$mergeObjects": [ "$$accessInfo", { "hasAccess": { "$eq": ["$$accessInfo.email", "user1@email.com"] } } ] } } } } ] } } } } } ]
为什么你的初始代码会报错?
你原来的管道里写的是"input": "$children0.access",这里的$children0本身是一个数组,所以$children0.access会返回一个二维数组(每个元素是children0里单个对象的access数组)。这就导致$map遍历的是数组的数组,每个$$accessInfo是一个数组而非单个对象,自然触发$mergeObjects的类型错误。
验证效果
用你提供的输入数据运行这个管道后,输出会变成:
[ { "nId": 0, "children0": [ { "nId": 3, "access": [ { "permission": "view", "email": "user1@email.com", "hasAccess": true } ] }, { "nId": 4, "access": [ { "permission": "view", "email": "user2@email.com", "hasAccess": false } ] } ] } ]
完全符合你想要的权限标记需求。
如果你的实际需求是给children0里的每个对象直接添加hasAccess(判断该对象的access数组中是否存在目标邮箱),也可以调整管道:
[ { "$addFields": { "children0": { "$map": { "input": "$children0", "as": "child", "in": { "$mergeObjects": [ "$$child", { "hasAccess": { "$in": ["user1@email.com", "$$child.access.email"] } } ] } } } } } ]
这个版本会给每个children0元素添加hasAccess字段,标记该元素的权限列表中是否包含目标用户。
内容的提问来源于stack exchange,提问作者Anonymous Creator
相关产品推荐
相关产品推荐

