在mongodb中更新数组中的多个元素

3

我在mongodb的库存集合中有一个如下所示的文档。

{ _id: 'xRMuRBhqRLgASyQyW',
  History: 
     [ { orderId: '12032017001877',
         status: 'COMPLETED',
        },
       { orderId: '22122017002450', 
        status: 'PROCESSED',
        },
        { orderId: '22122018002450', 
        status: 'DEPOSIT',
        }  
     ] 
 }

我希望遍历stocks集合中的所有文档,并在状态不是'PROCESSED'时添加一个字段flag: true

Sergio Tulentsev先生,您是在谈论历史数组吗?不,那个数组中有很多项。我正在尝试使用mongo shell更改我的数据库,因此没有客户端。 - Mritunjay Upadhyay
Mongo shell是客户端。 - Sergio Tulentsev
但那是一个GUI,不是一个shell。无论如何,shell也是一个客户端。除了数据库本身,一切都是客户端。 - Sergio Tulentsev
谢谢您先生。这是我的错误。 - Mritunjay Upadhyay
1
@AnthonyWinzlet:哦,这个对我来说是新的。谢谢,今天我学到了。 - Sergio Tulentsev
显示剩余3条评论
4个回答

14

你需要使用$[]位置操作符来更新数组中的每个元素。

db.collection.update(
   { "History": { "$elemMatch": { "status": { "$ne": "PROCESSED" } } } }, 
   { "$set": { "History.$[].flag": false } },
   { "multi": true }
)

2
先生,这是一个不错的代码,但我认为应该添加两个额外的参数(基本上是false和true,因为它们对我来说很合适)用于'upsert'和'multi'。我在这里写是因为'multi'需要更改多个文档。 - Mritunjay Upadhyay
你可以在多个文档上使用 multi 参数,但是不知道为什么这里要用 upsert - Ashh
先生,使用“upsert”将其设置为false,我们可以确保即使没有任何文档符合条件,也不会创建新的文档。 - Mritunjay Upadhyay
默认情况下,upsertfalse... 因此不需要写它... 但是如果您想确保,则可以将其设置为 false - Ashh
1
太棒了!这是更新数组中每个元素的完美答案。 - Harshal Yelpale
1
完美无瑕 - Bruno Morales

2
你可以使用脚本来实现这一点。
db.stocks.find().forEach(function (e) {
  var modified = false;
  e.History.forEach(function (o) {
    if (o.status != "PROCESSED") {
      o.flag = true;
      modified = true;
    }
  });
  if (modified) {
    db.stocks.save(e);
  }
});

我发现这是最好的选择,最适合我的问题。 - Mritunjay Upadhyay

1
您可以使用'$'运算符来简单地完成它。像这样:
 db.stocks.update( {"history.status" : { $not: "PROCESSED" } , 
                { $set: {"history.$.flag": true }} , 
                false , 
                true);

1
无法处理同一数组中的多个匹配项。 - Sergio Tulentsev

0

我的答案与 @Anthony 非常相似,但增加了两个额外的参数(用于 upsertmulti)。您可以参考 官方文档

db.stocks.update(
    { "History": { "$elemMatch": { "status": { "$ne": "PROCESSED" } } } }, 
    { "$set": { "History.$[].flag": false }},
     false,              // show that if there is not any document with specified criteria , it will not create a new document.
     ture              // according to document of mongodb if multi is true then more than one document will be updated, other wise only one document will be updated.
)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接