23

我有以下文件:

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

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

4

4 回答 4

33

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

于 2013-06-23T17:01:50.223 回答
7

您可以使用db.collection.bulkWrite()批量执行多项操作。自3.2.

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

于 2019-08-21T16:22:58.743 回答
5

从 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;
    }
   }

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

于 2020-04-04T06:32:28.763 回答
1

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

请参阅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") }
])

假设您不想将 misc1 和 misc2 字段分开,而是将它们收集到一个新的评论字段中。以下更新操作使用聚合管道来:

  • 添加新的评论字段并设置 lastUpdate 字段。
  • 删除集合中所有文档的 misc1 和 misc2 字段。
db.members.update(
  { },
  [
     { $set: { status: "Modified", comments: [ "$misc1", "$misc2" ], lastUpdate: "$$NOW" } },
     { $unset: [ "misc1", "misc2" ] }
  ],
  { multi: true }
)
于 2020-07-31T07:31:01.830 回答