mongodb MongoDB更新数组的多条记录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14720734/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 13:02:19  来源:igfitidea点击:

MongoDB update multiple records of array

arraysmongodb

提问by Viktor Kirilov

I recently started using MongoDB and I have a question regarding updating arrays in a document. I got structure like this:

我最近开始使用 MongoDB,我有一个关于更新文档中的数组的问题。我得到了这样的结构:

{
"_id" : ObjectId(),
"post" : "",
"comments" : [
        {
                "user" : "test",
                "avatar" : "/static/avatars/asd.jpg",
                "text" : "....."
        }
        {
                "user" : "test",
                "avatar" : "/static/avatars/asd.jpg",
                "text" : "....."
        }
        {
                "user" : "test",
                "avatar" : "/static/avatars/asd.jpg",
                "text" : "....."
        }
        ...
   ]
}

I'm trying to execute the following query:

我正在尝试执行以下查询:

update({"comments.user":"test"},{$set:{"comments.$.avatar": "new_avatar.jpg"}},false,true)

The problem is that it update all documents, but it update only the first array element in every document. Is there any way to update all array elements or I should try to do it manually? Thanks.

问题是它更新所有文档,但它只更新每个文档中的第一个数组元素。有没有办法更新所有数组元素,或者我应该尝试手动完成?谢谢。

回答by J Rassi

You cannot modify multiple array elements in a single update operation. Thus, you'll have to repeat the update in order to migrate documents which need multiple array elements to be modified. You can do this by iterating through each document in the collection, repeatedly applying an update with $elemMatchuntil the document has all of its relevant comments replaced, e.g.:

您不能在单个更新操作中修改多个数组元素。因此,您必须重复更新才能迁移需要修改多个数组元素的文档。您可以通过遍历集合中的每个文档,重复应用更新来实现此目的,$elemMatch直到文档的所有相关注释都被替换,例如:

db.collection.find().forEach( function(doc) {
  do {
    db.collection.update({_id: doc._id,
                          comments:{$elemMatch:{user:"test",
                                                avatar:{$ne:"new_avatar.jpg"}}}},
                         {$set:{"comments.$.avatar":"new_avatar.jpg"}});
  } while (db.getPrevError().n != 0);
})

Note that if efficiency of this operation is a requirement for your application, you should normalize your schema such that the location of the user's avatar is stored in a single document, rather than in every comment.

请注意,如果此操作的效率是您的应用程序的要求,您应该规范化您的架构,以便用户头像的位置存储在单个文档中,而不是每个评论中。

回答by David Welch

One solution could be creating a function to be used with a forEach and evaling it (so it runs quickly). Assuming your collection is "article", you could run the following:

一种解决方案可能是创建一个与 forEach 一起使用的函数并对其进行评估(因此它运行得很快)。假设您的收藏是“文章”,您可以运行以下命令:

var runUpdate = function(){
    db.article.find({"comments.user":"test").forEach( function(article) {
        for(var i in article.comments){
            article.comments[i].avatar = 'new_avatar.jpg';
        }
        db.article.save(article);
    });
};

db.eval(runUpdate);

回答by TBE

If you know the indexes you want to update you can do this with no problems like this:

如果您知道要更新的索引,则可以毫无问题地执行此操作:

var update = { $set: {} };
for (var i = 0; i < indexesToUpdate.length; ++i) {
  update.$set[`comments.${indexesToUpdate[i]}. avatar`] = "new_avatar.jpg";
}
Comments.update({ "comments.user":"test" }, update, function(error) {
  // ...
});
  • be aware that must of the IDE's will not accept the syntax but you can ignore it.
  • 请注意,IDE 的 must 不会接受该语法,但您可以忽略它。

回答by B T

It seems like you can do this:

看起来你可以这样做:

db.yourCollection.update({"comments.user":"test"},{$set:{"comments.0.avatar": "new_avatar.jpg", "comments.1.avatar": "new_avatar.jpg", etc...})

So if you have a small known number of array elements, this might be a little easier to do. If you want something like "comments.*.avatar" - not sure how to do that. It is probably not that good that you have so much data duplication tho..

因此,如果您有少量已知的数组元素,这可能会更容易一些。如果你想要“comments.*.avatar”之类的东西 - 不知道该怎么做。你有这么多的数据重复可能不是那么好。。