【问题标题】:way to update multiple documents with different values使用不同值更新多个文档的方法
【发布时间】:2013-06-16 22:17:21
【问题描述】:

我有以下文件:

[{
  "_id":1,
  "name":"john",
  "position":1
},
 {"_id":2,
  "name":"bob",
  "position":2
},
 {"_id":3,
  "name":"tom",
  "position":3
}]

在 UI 中,用户可以更改项目的位置(例如,将 Bob 移动到第一个位置,john 获得位置 2,tom - 位置 3)。 有没有办法一次更新所有文档中的所有位置?

【问题讨论】:

  • 1)。改变鲍勃的位置。 2)。在所有位置 > bob 的位置和
  • 谢谢,sashkello,一步改变位置的好方法。但我可以在 UI 客户端中对文档进行排序,排序后所有文档可能会更改其位置。
  • 如果有很多更新,我已将每个用户的排序顺序存储在不同的文档中以解决此问题。

标签: mongodb pymongo nosql


【解决方案1】:

您不能使用 MongoDB 查询一次更新两个文档。您将始终必须在两个查询中执行此操作。你当然可以设置一个字段的值到相同的值,或者以相同的数字递增,但是你不能在 MongoDB 中用相同的查询进行两次不同的更新。

【讨论】:

【解决方案2】:

您可以使用db.collection.bulkWrite() 批量执行多项操作。从3.2开始就可以使用了。

可以无序执行操作以提高性能。

【讨论】:

    【解决方案3】:

    从 mongodb 4.2 开始,您可以使用 $set 运算符在更新中使用管道

    由于聚合管道中有许多运算符,现在有很多可能的方法,尽管我提供了其中一种

        exports.updateDisplayOrder = async keyValPairArr => {
        try {
            let data = await ContestModel.collection.update(
                { _id: { $in: keyValPairArr.map(o => o.id) } },
                [{
                    $set: {
                        displayOrder: {
                            $let: {
                                vars: { obj: { $arrayElemAt: [{ $filter: { input: keyValPairArr, as: "kvpa", cond: { $eq: ["$$kvpa.id", "$_id"] } } }, 0] } },
                                in:"$$obj.displayOrder"
                            
                            }
                        }
                    }
                }],
                { runValidators: true, multi: true }
            )
    
            return data;
        } catch (error) {
            throw error;
        }
       }
    

    示例键值对是:[{"id":"5e7643d436963c21f14582ee","displayOrder":9}, {"id":"5e7643e736963c21f14582ef","displayOrder":4}]

    【讨论】:

    • 您能否更详细地解释您的答案,特别是 (vars) (obj) ($arrayElemAt) (input) 和 (as: "kvpa", cond: { $eq: ["$$kvpa. id", "$_id"] } } }, 0]) 关键字。因为我有一个对象数组,每个对象都包含 product_id 和数量,我想查询产品集合以根据客户购买的数量更新(减少)每个产品库存!提前谢谢!
    • 你其实不需要写前两行,只是我匹配特定文档的_id,然后在数组中找到位置,然后更新正确的值
    • 对聚合过程的深刻理解!
    【解决方案4】:

    由于 MongoDB 4.2 update 可以接受聚合管道作为第二个参数,允许根据数据修改多个文档。

    见https://docs.mongodb.com/manual/reference/method/db.collection.update/#modify-a-field-using-the-values-of-the-other-fields-in-the-document

    文档摘录:

    使用文档中其他字段的值修改字段

    创建一个包含以下文档的成员集合:

    db.members.insertMany([
      { "_id" : 1, "member" : "abc123", "status" : "A", "points" : 2, "misc1" : "note to self: confirm status", "misc2" : "Need to activate", "lastUpdate" : ISODate("2019-01-01T00:00:00Z") },
      { "_id" : 2, "member" : "xyz123", "status" : "A", "points" : 60, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment", "lastUpdate" : ISODate("2019-01-01T00:00:00Z") }
    ])
    

    假设您希望将它们收集到一个新的 cmets 字段中,而不是单独的 misc1 和 misc2 字段。以下更新操作使用聚合管道:

    • 添加新的 cmets 字段并设置 lastUpdate 字段。
    • 删除集合中所有文档的 misc1 和 misc2 字段。
    db.members.update(
      { },
      [
         { $set: { status: "Modified", comments: [ "$misc1", "$misc2" ], lastUpdate: "$$NOW" } },
         { $unset: [ "misc1", "misc2" ] }
      ],
      { multi: true }
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-29
      • 1970-01-01
      • 1970-01-01
      • 2013-05-15
      • 2016-08-29
      • 2020-07-21
      • 2020-11-19
      相关资源
      最近更新 更多