MongoDB:向activities集合users数组添加非重复用户(带默认分数)
MongoDB 向activities集合的users数组添加不存在的用户(不覆盖已有分数)
要实现仅将指定用户ID列表中未存在的用户添加到activities集合文档的users数组,同时保留已有用户的scores不被覆盖,可以使用MongoDB的聚合管道更新完成,具体操作如下:
核心更新命令
// 更新单个指定文档(根据_id匹配) db.activities.updateOne( { _id: ObjectId("目标文档ID") }, // 替换为实际的文档匹配条件 [ { $set: { users: { $concatArrays: [ "$users", // 保留原有的用户数组 { $map: { // 筛选出需要添加的用户ID(列表中不存在于现有users的ID) input: { $setDifference: [ [2, 3], // 替换为你的目标用户ID列表 "$users.userId" ] }, as: "newUserId", // 将筛选出的ID转换为带默认分数的用户对象 in: { userId: "$$newUserId", scores: { failures: 0, wins: 0 } // 替换为你的默认分数配置 } } } ] } } } ] )
逻辑说明
- 筛选待添加用户:通过
$setDifference计算目标用户ID列表与现有users.userId数组的差集,得到所有需要新增的用户ID。 - 转换为用户对象:用
$map把差集中的每个ID转换成包含默认scores的用户对象。 - 拼接数组:使用
$concatArrays将原users数组和新生成的用户对象数组合并,得到最终的users数组。
效果验证
假设原users数组为:
[{ userId: 1, scores: { failures: 2, wins: 4 } }, { userId: 2, scores: { failures: 0, wins: 2 } }]
目标用户ID列表为[2, 3],默认分数为{ failures: 0, wins: 0 },执行更新后,users数组会变为:
[{ userId: 1, scores: { failures: 2, wins: 4 } }, { userId: 2, scores: { failures: 0, wins: 2 } }, { userId: 3, scores: { failures: 0, wins: 0 } }]
仅userId为3的用户被添加,userId为2的已有用户分数完全保留。
批量更新所有文档
如果需要对集合中所有文档执行此操作,只需将updateOne替换为updateMany,匹配条件改为{}即可:
db.activities.updateMany( {}, [ { $set: { users: { $concatArrays: [ "$users", { $map: { input: { $setDifference: [ [2, 3], "$users.userId" ] }, as: "newUserId", in: { userId: "$$newUserId", scores: { failures: 0, wins: 0 } } } } ] } } } ] )
内容的提问来源于stack exchange,提问作者fullstack
相关产品推荐
相关产品推荐

