我有一个Mongo文档,其中包含一个元素数组。
我想重置.profile = XX数组中所有对象的.handled属性。
文件格式如下:
{
"_id": ObjectId("4d2d8deff4e6c1d71fc29a07"),
"user_id": "714638ba-2e08-2168-2b99-00002f3d43c0",
"events": [{
"handled": 1,
"profile": 10,
"data": "....."
} {
"handled": 1,
"profile": 10,
"data": "....."
} {
"handled": 1,
"profile": 20,
"data": "....."
}
...
]
}
所以,我尝试了以下方法:
.update({"events.profile":10},{$set:{"events.$.handled":0}},false,true)
但是,它只更新每个文档中第一个匹配的数组元素。(这是$ -位置操作符的定义行为。)
如何更新所有匹配的数组元素?
实际上,save命令只在Document类的实例上。
有很多方法和属性。因此可以使用lean()函数来减少工作负载。
请参考这里。https://hashnode.com/post/why-are-mongoose-mongodb-odm-lean-queries-faster-than-normal-queries-cillvawhq0062kj53asxoyn7j
保存功能的另一个问题是,同时在多个保存中会产生冲突数据。
模型。更新将使数据一致。
因此要更新文档数组中的多个项目。使用你熟悉的编程语言,尝试这样的东西,我用mongoose:
User.findOne({'_id': '4d2d8deff4e6c1d71fc29a07'}).lean().exec()
.then(usr =>{
if(!usr) return
usr.events.forEach( e => {
if(e && e.profile==10 ) e.handled = 0
})
User.findOneAndUpdate(
{'_id': '4d2d8deff4e6c1d71fc29a07'},
{$set: {events: usr.events}},
{new: true}
).lean().exec().then(updatedUsr => console.log(updatedUsr))
})
实际上,save命令只在Document类的实例上。
有很多方法和属性。因此可以使用lean()函数来减少工作负载。
请参考这里。https://hashnode.com/post/why-are-mongoose-mongodb-odm-lean-queries-faster-than-normal-queries-cillvawhq0062kj53asxoyn7j
保存功能的另一个问题是,同时在多个保存中会产生冲突数据。
模型。更新将使数据一致。
因此要更新文档数组中的多个项目。使用你熟悉的编程语言,尝试这样的东西,我用mongoose:
User.findOne({'_id': '4d2d8deff4e6c1d71fc29a07'}).lean().exec()
.then(usr =>{
if(!usr) return
usr.events.forEach( e => {
if(e && e.profile==10 ) e.handled = 0
})
User.findOneAndUpdate(
{'_id': '4d2d8deff4e6c1d71fc29a07'},
{$set: {events: usr.events}},
{new: true}
).lean().exec().then(updatedUsr => console.log(updatedUsr))
})
您可以更新MongoDB中的所有元素
db.collectioname.updateOne(
{ "key": /vikas/i },
{ $set: {
"arr.$[].status" : "completed"
} }
)
它将更新“arr”数组中所有的“status”值为“completed”
如果只有一份文件
db.collectioname.updateOne(
{ key:"someunique", "arr.key": "myuniq" },
{ $set: {
"arr.$.status" : "completed",
"arr.$.msgs": {
"result" : ""
}
} }
)
但如果不是一个,而且你也不希望数组中的所有文档都更新,那么你需要遍历元素和if块内部
db.collectioname.find({findCriteria })
.forEach(function (doc) {
doc.arr.forEach(function (singlearr) {
if (singlearr check) {
singlearr.handled =0
}
});
db.collection.save(doc);
});
这个帖子很老了,但我来这里寻找答案,因此提供了新的解决方案。
在MongoDB 3.6+版本中,现在可以使用位置操作符更新数组中的所有项。点击这里查看官方文件。
下面的问题将适用于这里提出的问题。我也用Java-MongoDB驱动进行了验证,工作成功。
.update( // or updateMany directly, removing the flag for 'multi'
{"events.profile":10},
{$set:{"events.$[].handled":0}}, // notice the empty brackets after '$' opearor
false,
true
)
希望这能帮助到像我这样的人。