MongoDB 更新 $in

MongoDB upsert $in

我有一堆记录要为特定产品 ID 插入。根据之前的计算,我想记录该产品在当前 week/year.

中的类型

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

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 是一个数组,并尝试匹配和更新数组中的每个项目。除非那不起作用。

非常感谢任何帮助。

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

product_id: { $in: a_group }

product_id: { $in: productsId },

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

来自文档:

An upsert:

  • Updates documents that match your query filter
  • Inserts a document if there are no matches to your query filter

在更新插入的情况下,例如:

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

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

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

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

使用 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)

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