MongoDB如何通过单条请求移除数组中3个指定相同元素
MongoDB单请求删除数组中指定数量匹配元素实现方法
需求背景
需要单次数据库请求完成数组元素删除,不允许多次交互:
- 原文档内容:
{ "_id" : 1, "items" : ["Test", "Test", "Test", "Test", "Test", "Sword", "Sword"]}
- 预期执行结果:仅删除3个值为
"Test"的元素,剩余2个"Test"和原有其他元素,最终文档为
{ "_id" : 1, "items" : ["Test", "Test", "Sword", "Sword"]}
操作语句
直接使用4.2及以上版本支持的聚合管道更新即可,单原子请求完成操作,语句如下:
// 替换为你实际使用的集合名 db.itemCollection.updateOne( // 匹配目标文档 { _id: 1 }, [ { $set: { items: { $let: { vars: { // 提取所有非Test的元素 keepOther: { $filter: { input: "$items", cond: { $ne: ["$$this", "Test"] } } }, // 统计原数组中Test的总个数 testCount: { $size: { $filter: { input: "$items", cond: { $eq: ["$$this", "Test"] } } } } }, in: { $concatArrays: [ // 保留 总Test数-3 个Test,即实现删除3个Test的效果 { $map: { input: { $range: [0, { $subtract: ["$$testCount", 3] }] }, in: "Test" } }, // 拼接上其他不需要删除的元素 "$$keepOther" ] } } } } } ] )
注意事项
- 不要用常规的
$pull操作符,它会把数组中所有值为"Test"的元素全部删除,最终只剩["Sword", "Sword"],不符合保留2个Test的要求 - 该操作是单请求原子执行,不存在并发修改问题,性能和普通更新操作一致
- 该方案兼容所有4.2及以上版本的MongoDB,目前生产环境绝大多数部署版本都满足要求,如果是低于4.2的版本,无法在单请求内实现该需求,必须先查询文档内容再做更新。
内容的提问来源于stack exchange,提问作者Nice
相关产品推荐
相关产品推荐

