MongoDB中$inc操作不生效求助:更新嵌套数组指定字段
解决MongoDB数组多元素unread字段自增的问题
嗨,我来帮你搞定这个数组更新的问题!你遇到的情况是因为原来的写法没用到正确的数组更新操作符,导致$inc没生效,具体原因和解决方法如下:
为啥原来的写法不行?
你用的$(位置操作符)只能匹配数组里第一个符合facebookId: {$ne: "-1"}的元素,而且multi: true这个参数是用来更新多个文档的,不是更新单个文档里的多个数组元素。所以要么只有第一个符合条件的元素被更新,要么如果文档里第一个数组元素是facebookId:"-1"的话,就完全不会触发更新。
正确的写法(MongoDB 3.2+适用)
要实现“更新数组中所有facebookId不等于-1的元素的unread字段”,得用MongoDB 3.2及以上版本支持的过滤数组更新操作符$[<identifier>],具体代码如下:
chat.update( { "_id": { "$in": chatId } }, // 先匹配要更新的目标文档 { "$inc": { "users.$[user].unread": 1 } // 对符合过滤条件的数组元素自增 }, { multi: true, // 如果chatId里有多个_id,需要保留这个参数来更新多个文档;单个文档的话可以去掉 arrayFilters: [ { "user.facebookId": { "$ne": "-1" } } ] // 定义数组元素的过滤规则 }, function(err, data) { if (err) throw err; console.log(data); } );
代码拆解一下
- 查询条件:只保留匹配文档的
_id条件就行,数组元素的过滤规则不用写在这里,而是放在arrayFilters里。 - 更新逻辑:
$[user]是一个占位符,对应arrayFilters里的user标识符,这样所有符合user.facebookId != "-1"的数组元素都会被$inc操作命中。 - 参数说明:
multi: true是用来批量更新多个文档的,如果你的chatId数组只有一个_id,这个参数可以省略。
验证效果
用你给出的原始数据测试:
{ "_id": "5aa8f087e1eee70004a99e1d", "users": [ { "facebookId": "-1", "unread": 0 }, { "facebookId": "323232321", "unread": 1 } ] }
执行更新后,数据会变成:
{ "_id": "5aa8f087e1eee70004a99e1d", "users": [ { "facebookId": "-1", "unread": 0 }, { "facebookId": "323232321", "unread": 2 } ] }
完全符合你的需求。
最后别忘了确认一下你的MongoDB版本哦,3.2以下的版本不支持arrayFilters这个功能~
内容的提问来源于stack exchange,提问作者Sandeep Ranjan
相关产品推荐
相关产品推荐

