为了账号安全,请及时绑定邮箱和手机立即绑定

MongoDB-更新文档数组中的对象(嵌套更新)

/ 猿问

MongoDB-更新文档数组中的对象(嵌套更新)

qq_笑_17 2019-06-20 16:55:24

MongoDB-更新文档数组中的对象(嵌套更新)

假设我们有以下集合,我对此几乎没有问题:

{
    "_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-我想提高“项目名称”的价格:“我的项目2”如果它不存在,它应该附加到“Item”数组中。

2-如何同时更新两个字段。例如,增加“my_tem_3”的价格,同时增加“总计”(具有相同的值)。

我更喜欢在MongoDB端这样做,否则我必须在客户端(Python)加载文档,并构造更新的文档并将其替换为MongoDB中的现有文档。

更新这就是我尝试过的,而且效果很好。如果对象存在 :

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

但如果钥匙不存在,它什么也做不了。此外,它只更新嵌套的对象。使用此命令也无法更新“总计”字段。


查看完整描述

2 回答

?
FFIVE

对于问题1,让我们将其分为两部分。首先,增加任何具有“items.tem_name”等于“my_tem_2”的文档。为此,您必须使用位置“$”操作符。类似于:

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

请注意,这只会在任何数组中增加第一个匹配的子文档(因此,如果数组中有另一个文档,其“Item_name”等于“my_tem_2”,则不会增加)。但这可能是你想要的。

第二部分比较棘手。我们可以将一个新项推送到没有“my_tem_2”的数组中,如下所示:

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

对于你的第二个问题,答案更简单。要在包含“My_Item_3”的任何文档中增加项目3的总量和价格,可以同时在多个字段上使用$inc运算符。类似于:

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


查看完整回答
反对 回复 2019-06-20
?
慕粉4167745

在单个查询中无法做到这一点。您必须在第一个查询中搜索文档:

如果存在文件:

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

其他

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

不需要添加条件{$ne : "my_item_two" }.

另外,在多线程环境中,您必须小心,每次只有一个线程可以执行第二个线程(如果没有找到文档,则是插入情况),否则会插入重复的嵌入文档。


查看完整回答
反对 回复 2019-06-20

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信