【问题标题】:Mongoose updateMany dynamicallyMongoose updateMany 动态
【发布时间】:2022-01-23 18:53:09
【问题描述】:

我有一个看起来像这样的集合(为简洁起见删除了字段):

[
    { "id": "A", "name": "AA" ,"arrayField": [1, 2, 3] },
    { "id": "B", "name": "BB" ,"arrayField": [4, 5, 6] },
    { "id": "C", "name": "CC" ,"arrayField": [7, 8] }
]

将每个对象视为一个文档。


现在在我的应用程序中,经过一些业务逻辑,我有一个 POJO 数组,如下所示:

[
    { "id": "A", "name": "AB", "arrayField": [1, 2, 3] },
    { "id": "B", "name": "VB", "arrayField": [4, 5, 6] },
    { "id": "C", "name": "DE", "arrayField": [7, 8] }
    { "id": "D", "name": "GG", "arrayField": [10, 11] }
]

请注意,这些对象没有文档所需的其他字段。

如何更新 MongoDB 集合以反映与对象数组中的相同?

  • 我想id A、B** 和CarrayField 和name 字段/strong> 反映对象数组。
  • 还有一个带有id D 的新文档必须插入到集合中(其他字段将得到处理,因为它们在架构中具有默认值)。李>

我尝试过/想到的事情

注意:arr 是正在讨论的对象数组。

  1. updateManyupsert

    Model.updateMany({ id: { $in: arr.map(({ id }) => id) } }, arr, { upsert: true });
    
  2. 映射对象数组并使用 upsert 更新:

    await Promise.all(
        arr.map(({ id, arrayField, name }) => {
            return Model.updateOne({ id }, { $set: { arrayField, name } }, { upsert: true });
        })
    );
    

有没有办法使用事务/聚合/等来做到这一点?

【问题讨论】:

  • 事务用于对给定会话中的多个查询进行分组,并允许您在其中任何一个出现问题时回滚。聚合使您有机会在查询期间塑造和过滤数据。我不认为这对你有帮助。您需要他们做的哪些解决方案没有为您做?
  • @NathanWiles 抱歉,我不知道交易到底是什么。谈到聚合,我已经看到您可以在一个阶段关联一个“变量”并使用它来更新/查找。来到解决方案,第一个不起作用。数据库保持不变。另外,它不会替换整个文档而不仅仅是我想要更改的字段吗?第二种解决方案可以完成工作!但是它不会需要 N 次访问数据库,其中 N 是 arr 的长度吗?
  • @Abhijit 我认为 Nathan 做了一个合理的说明。对于您的第二个解决方案,如果您唯一关心的是访问数据库的次数,bulk operation 可能就是您要寻找的。​​span>
  • @ray 批量操作看起来不错。会试试的!谢谢你们俩。

标签: node.js mongodb mongoose mongodb-query aggregate-functions


【解决方案1】:

正如@ray 在 cmets 中建议的那样,我正在寻找 bulk operations。我做了一些类似的事情:

const bulk = Model.initializeUnorderdBulkOp();
arr.forEach(({ id, arrayField, name }) => {
    bulk.find({ id }).upsert().updateOne({ $set: { arrayField, name } });
});
bulk.execute();

【讨论】:

    猜你喜欢
    • 2020-03-26
    • 2021-06-29
    • 1970-01-01
    • 2020-04-04
    • 2023-03-09
    • 2020-07-09
    • 2020-12-16
    • 2021-09-03
    • 1970-01-01
    相关资源
    最近更新 更多