MongoDB-更新文档数组中的对象(嵌套更新) [英] MongoDB - Update objects in a document's array (nested updating)

查看:114
本文介绍了MongoDB-更新文档数组中的对象(嵌套更新)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有以下收藏,对此我有几个疑问:

Assume we have the following collection, which I have few questions about:

{
    "_id" : ObjectId("4faaba123412d654fe83hg876"),
    "user_id" : 123456,
    "total" : 100,
    "items" : [
            {
                    "item_name" : "my_item_one",
                    "price" : 20
            },
            {
                    "item_name" : "my_item_two",
                    "price" : 50
            },
            {
                    "item_name" : "my_item_three",
                    "price" : 30
            }
    ]
}

1-我想提高"item_name":"my_item_two"的价格,如果不存在,则应将其附加到"items"数组中.

1 - I want to increase the price for "item_name":"my_item_two" and if it doesn't exists, it should be appended to the "items" array.

2-如何同时更新两个字段.例如,增加"my_item_three"的价格,同时增加"total"(具有相同的值).

2 - How can I update two fields at the same time. For example, increase the price for "my_item_three" and at the same time increase the "total" (with the same value).

我更喜欢在MongoDB上执行此操作,否则我必须将文档加载到客户端(Python)中并构造更新的文档,并将其替换为MongoDB中现有的文档.

I prefer to do this on the MongoDB side, otherwise I have to load the document in client-side (Python) and construct the updated document and replace it with the existing one in MongoDB.

更新 这是我尝试过的并且可以正常运行的如果对象存在:

UPDATE This is what I have tried and works fine IF THE Object Exists :

db.test_invoice.update({user_id : 123456 , "items.item_name":"my_item_one"} , {$inc: {"items.$.price": 10}})

但是,如果密钥不存在,则不会执行任何操作. 同样,它仅更新嵌套对象.此命令也无法更新总计"字段.

But if the key doesn't exist it does nothing. Also it only updates the nested object. There is no way with this command to update the "total" field as well.

推荐答案

对于问题1,我们将其分为两部分.首先,增加具有"items.item_name"等于"my_item_two"的任何文档.为此,您必须使用位置"$"运算符.像这样:

For question #1, let's break it into two parts. First, increment any document that has "items.item_name" equal to "my_item_two". For this you'll have to use the positional "$" operator. Something like:

 db.bar.update( {user_id : 123456 , "items.item_name" : "my_item_two" } , 
                {$inc : {"items.$.price" : 1} } , 
                false , 
                true);

请注意,这只会递增任何数组中的第一个匹配子文档(因此,如果数组中的另一个文档的"item_name"等于"my_item_two",则不会递增).但这可能就是您想要的.

Note that this will only increment the first matched subdocument in any array (so if you have another document in the array with "item_name" equal to "my_item_two", it won't get incremented). But this might be what you want.

第二部分比较棘手.我们可以将新项目推入不带"my_item_two"的数组,如下所示:

The second part is trickier. We can push a new item to an array without a "my_item_two" as follows:

 db.bar.update( {user_id : 123456, "items.item_name" : {$ne : "my_item_two" }} , 
                {$addToSet : {"items" : {'item_name' : "my_item_two" , 'price' : 1 }} } ,
                false , 
                true);

对于您的问题2,答案更简单.要增加任何包含"my_item_three"的文档中item_three的总数和价格,可以同时在多个字段上使用$ inc运算符.像这样:

For your question #2, the answer is easier. To increment the total and the price of item_three in any document that contains "my_item_three," you can use the $inc operator on multiple fields at the same time. Something like:

db.bar.update( {"items.item_name" : {$ne : "my_item_three" }} ,
               {$inc : {total : 1 , "items.$.price" : 1}} ,
               false ,
               true);

这篇关于MongoDB-更新文档数组中的对象(嵌套更新)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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