MongoDB如何对匹配到的同一数组成员同时执行字段更新和push操作
解决方案
你提到的在同个updateOne查询中同时使用$push和$set的逻辑本身是MongoDB原生支持的,你遇到报错大概率是语法书写错误(比如漏写逗号、引号不匹配等),正确的写法如下:
await User.updateOne( { _id: userId, sportsList: { $elemMatch: { name: 'tennis' } } }, { $push: { 'sportsList.$.levelHistory': { date: new Date(), from: 1400, to: 1450 } }, // positional $ 操作符会自动匹配前面$elemMatch命中的数组元素 $set: { 'sportsList.$.level': 1450 } } )
如果你使用的是MongoDB 3.6及以上版本,更推荐使用带过滤标识符的数组更新写法,匹配逻辑更清晰,也能避免复杂数组场景下$位置操作符匹配错误的问题:
await User.updateOne( { _id: userId }, { $push: { 'sportsList.$[sport].levelHistory': { date: new Date(), from: 1400, to: 1450 } }, $set: { 'sportsList.$[sport].level': 1450 } }, { // 数组过滤条件,仅匹配name为tennis的元素 arrayFilters: [ { 'sport.name': 'tennis' } ] } )
注意事项:
- 确保更新操作符
$push和$set在更新对象的同一层级,不要嵌套到其他操作符内部 - 不要对同一个字段路径同时使用多个更新操作符,会触发MongoDB冲突报错,本场景中两个操作符分别作用于
levelHistory和level两个不同字段,不存在冲突
内容的提问来源于stack exchange,提问作者Gabriel Lupu
相关产品推荐
相关产品推荐

