MongoDB更新数组错误的所有字段 [英] MongoDB update all fields of array error

查看:69
本文介绍了MongoDB更新数组错误的所有字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

试图将ID为0的文档的items.qty设置为0.

Im tring to set 0 the items.qty of a document obtains by a id query.

db.warehouses.update(
    // query 
    {
        _id:ObjectId('5322f07e139cdd7e31178b78')
    },    
    // update 
    {
        $set:{"items.$.qty":0}
    },    
    // options 
    {
        "multi" : true,  // update only one document 
        "upsert" : true  // insert a new document, if no existing document match the query 
    }
);

返回:

在没有包含数组的相应查询字段的情况下,无法应用位置运算符.

Cannot apply the positional operator without a corresponding query field containing an array.

这是我要将所有items.qty设置为0的文档

This is the document that i want to set all items.qty to 0

{
  "_id": { "$oid" : "5322f07e139cdd7e31178b78" },
  "items": [
    {
      "_id": { "$oid" : "531ed4cae604d3d30df8e2ca" },
      "brand": "BJFE",
      "color": "GDRNCCD",
      "hand": 1,
      "model": 0,
      "price": 500,
      "qty": 0,
      "type": 0
    },
    {
      "brand": "BJFE",
      "color": "GDRNCCD",
      "hand": 1,
      "id": "23",
      "model": 0,
      "price": 500,
      "qty": 4,
      "type": 0
    },
    {
      "brand": "BJFE",
      "color": "GDRNCCD",
      "hand": 1,
      "id": "3344",
      "model": 0,
      "price": 500,
      "qty": 6,
      "type": 0
    }
  ],
  "name": "a"
}

推荐答案

编辑

该问题缺少的细节是,要更新的必填字段实际上在子文档中.这大大改变了答案:

EDIT

The detail missing from the question was that the required field to update was actually in a sub-document. This changes the answer considerably:

这是您可能只能执行的操作来约束更新数组元素. 文档中对此进行了明确说明.主要在本段中:

This is a constraint of what you can possibly do with updating array elements. And this is clearly explained in the documentation. Mostly in this paragraph:

位置$运算符充当与查询文档匹配的 first 元素的占位符

这就是问题.试图像这样在单个语句中更新所有数组元素的所有有效.为此,您必须执行以下操作.

So here is the thing. Trying to update all of the array elements in a single statement like this will not work. In order to do this you must to the following.

db.warehouses.find({ "items.qty": { "$gt": 0 } }).forEach(function(doc) {
    doc.items.forEach(function(item) {
        item.qty = 0;
    });
    db.warehouses.update({ "_id": doc._id }, doc );
})

基本上,这是更新每个数组元素的方法.

Which is basically the way to update every array element.

.update()中的 multi 设置表示跨多个文档". 不能将其应用于数组的多个元素.因此,目前最好的选择是替换整个东西.或者在这种情况下,我们也可以替换整个文档,因为我们仍然需要这样做.

The multi setting in .update() means across multiple "documents". It cannot be applied to multiple elements of an array. So presently the best option is to replace the whole thing. Or in this case we may just as well replace the whole document since we need to do that anyway.

对于真实批量数据,请使用 db.eval() .但是请先阅读文档:

For real bulk data, use db.eval(). But please read the documentation first:

db.eval(function() {
    db.warehouses.find({ "items.qty": { "$gt": 0 } }).forEach(function(doc) {
        doc.items.forEach(function(item) {
            item.qty = 0;
        });
        db.warehouses.update({ "_id": doc._id }, doc );
    });
})

更新整个集合中数组中的所有元素并不简单.

Updating all the elements in an array across the whole collection is not simple.

错误确切地说.为了使用位置运算符,您需要先匹配.如:

Pretty much exactly what the error says. In order to use a positional operator you need to match something first. As in:

db.warehouses.update(
    // query 
    {
        _id:ObjectId('5322f07e139cdd7e31178b78'),
        "items.qty": { "$gt": 0 }
    },    
    // update 
    {
        $set:{"items.$.qty":0}
    },    
    // options 
    {
        "multi" : true,  
        "upsert" : true  
    }
);

因此,当 match 条件使小于 0的项目在位置处定位,然后在该索引传递给位置运算符.

So where the match condition fins the position of the items that are less than 0 then that index is passed to the positional operator.

P.S :当 muti true 时,表示它会更新每个文档.如果您仅表示一个,则将其保留为false.这是默认设置.

P.S : When muti is true it means it updates every document. Leave it false if you only mean one. Which is the default.

这篇关于MongoDB更新数组错误的所有字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆