【问题标题】:Mongodb update multiple documents with different valuesMongodb 更新多个具有不同值的文档
【发布时间】:2020-01-14 06:27:07
【问题描述】:

我一直在尝试将updatemany 与猫鼬一起使用。我想使用对象数组更新数据库中的值。

[
            {
                "variantId": "5e1760fbdfaf28038242d676",
                "quantity": 5

            },
            {
                    "variantId": "5e17e67b73a34d53160c7252",
                    "quantity": 13
            }
            ]

我想使用 variantId 作为过滤器。 模型架构是:

let variantSchema = new mongoose.Schema({
    variantName: String,
    stocks: {
        type: Number,
        min: 0
    },
    regularPrice: {
        type: Number,
        required: true
    },
    salePrice: {
        type: Number,
        required: true
    }
})

我想使用 variantId 过滤模型,然后减少库存。

【问题讨论】:

  • 我认为这不能通过 updateMany 调用来完成,因为您需要将每个文档的库存值减少一个不同的数字。
  • @Vidhyanshu jain:为什么您的架构和示例文档看起来完全不同?你需要猫鼬模式的帮助还是只需要查询?
  • @srinivasy 这不是一个示例文档,而是我收到的一个 json,我将根据 json 的值更新这些值。
  • @Vidhyanshujain : 这个输入 variantId & quantity 与实际文档中的匹配是什么?
  • @srinivasy variantId 与变体模型的对象 id 匹配。数量会减少库存的价值

标签: node.js mongodb mongoose mongoose-schema


【解决方案1】:

由于您需要使用多个条件更新多个文档,因此 .updateMany() 将不起作用 - 只有当您需要更新具有相同值的多个文档时它才会起作用,请尝试以下查询,这将帮助您完成它一个数据库调用:

const Mongoose = require("mongoose");

let variantSchema = new mongoose.Schema({
    variantName: String,
    stocks: {
        type: Number,
        min: 0
    },
    regularPrice: {
        type: Number,
        required: true
    },
    salePrice: {
        type: Number,
        required: true
    }
})

const Variant = mongoose.model('variant', variantSchema, 'variant');

let input = [
    {
        "variantId": "5e1760fbdfaf28038242d676",
        "quantity": 5

    },
    {
        "variantId": "5e17e67b73a34d53160c7252",
        "quantity": 13
    }
]

let bulkArr = [];

for (const i of input) {
    bulkArr.push({
        updateOne: {
            "filter": { "_id": Mongoose.Types.ObjectId(i.variantId) },
            "update": { $inc: { "stocks": - i.quantity } }
        }
    })
}

Variant.bulkWrite(bulkArr)

参考: MongoDB-bulkWrite

【讨论】:

  • 非常感谢,这似乎有效,但我遇到了另一个问题,在对应该抛出错误的查询进行了 blukwrite 之后。 Bulkwrite 不会引发错误。
  • @Vidhyanshujain : Bulkwrite 将导致 writerresult 检查查询的响应或在 writeErrors 部分中抛出文档错误,在该链接中检查最后几个有用的部分。
【解决方案2】:

我认为这不能通过单个 Model.updateMany 查询来完成。您将需要循环数组并改用Model.update

for (const { variantId, quantity } of objects) {
    Model.update({ _id: variantId }, { $inc: { stocks: -quantity } });
}

要在事务 (https://mongoosejs.com/docs/transactions.html) 中运行此代码,代码应如下所示(但我尚未尝试或测试过):

mongoose.startSession().then(async session => {
    session.startTransaction();

    for (const { variantId, quantity } of objects) {
        await Model.update({ _id: variantId }, { $inc: { stocks: -quantity } }, { session });
    }

    await session.commitTransaction();
});

【讨论】:

  • 这将是一个异步调用,我有什么办法可以使同步,因为我必须在事务中使用它? @gutnar
  • 我会去寻找@srinivasy 给出的答案,使用bulkWrite 代替它看起来更好。
猜你喜欢
  • 2016-12-29
  • 2017-02-14
  • 1970-01-01
  • 2013-05-15
  • 1970-01-01
  • 2016-08-29
  • 1970-01-01
  • 1970-01-01
  • 2021-12-27
相关资源
最近更新 更多