MongoDB 更新插入 $in

Posted

技术标签:

【中文标题】MongoDB 更新插入 $in【英文标题】:MongoDB upsert $in 【发布时间】:2021-10-26 15:20:16 【问题描述】:

我有一堆记录要更新插入特定的产品 ID。根据之前的计算,我想记录该产品在当前周/年的类型。

问题是我想不出一种方法来做到这一点,除了一次一个。现在我在做:

a_group.forEach(p => 
    db.abc.update(
        product_id: p._id,
        year: 2021
    ,  
        $set:  
            'abc.34': 'a'
        
    , 
        upsert: true
    );
);

a_group 只是一系列产品。

如果产品阵列很大,这确实很重。它只是执行a_group.length upsert 操作。

理想情况下,我想做这样的事情:

db.abc.update(
    product_id:  $in: a_group.map(p => p._id) ,
    year: 2021
, 
    $set: 
        'abc.34': 'a'
    
, 
    upsert: true,
    multi: true
);

这将看到 a_group 是一个数组,并尝试匹配并更新数组中的每个项目。除非那行不通。

非常感谢任何帮助。

【问题讨论】:

您是直接在 mongodb shell 中、通过 mongodb js 驱动程序还是从 Meteor(在集合上)执行此操作? @ChristianFritz 我明白你为什么这么问。试图简化代码的另一个错误。在 Meteor 中将是 ABC.update()。我在 Meteor 中做ABC.rawCollection() 使用@Joe 的解决方案。 【参考方案1】:

这里的问题是您需要为 _id 的每个离散值单独更新插入。

来自文档:

一个更新:

更新与您的查询过滤器匹配的文档 如果没有与您的查询过滤器匹配的文档,则插入文档

在 upsert 的情况下,例如:

updateMany(
    a:$in[1,2,3],
    $set:b:true,   
    upsert: true
)

如果存在包含a: 3 的文档,那么它将匹配查询过滤器,因此将更新一个文档,并且不会发生插入。

如果没有文档与传递给$in 的任何值匹配,则将插入一个单个新文档。由于查询无法确定您想要的a 的值,因此它将创建一个包含b:true 的文档,但将留下a 未定义。

您可能想要的是一个批量操作,它可以通过一次调用数据库来执行许多 upsert 操作。

使用 mongosh shell,可能看起来像:

let ops = [];
a_group.forEach(p => 
   ops.push(
     updateOne:
       
         filter: 
                  product_id: p._id,
                  year: 2021
         ,
         update: $set: 'abc.34': 'a',
         upsert: true
    
   );
);
db.abc.bulkWrite(ops)

查看您正在使用的驱动程序的文档,了解如何进行批量操作。

【讨论】:

【参考方案2】:

根据您的代码,我认为 a_group 是对象数组,因为您在 forEach 中使用 p._id , 您应该从a_group 导出_id 并推入新数组,例如productsId 并替换

product_id:  $in: a_group 

product_id:  $in: productsId ,

【讨论】:

对不起,我的实际代码就是这种情况。我尝试简化示例,以便更容易讨论实际问题,但似乎略有疏忽。我已经更正了示例代码。

以上是关于MongoDB 更新插入 $in的主要内容,如果未能解决你的问题,请参考以下文章

???????????????????????? - ???????(IN MONGODB)

解析服务器在 mongodb 中创建相同的 objectid

Mongoose (mongodb) 批量插入、删除、更新和无操作

Nodejs,mongodb在插入许多后更新数组

插入、更新或删除 MongoDB 或 SQL 哪个更快?

MongoDB文档--插入更新删除