是否可以通过替换字段(documents(数组使用MongoDB批量更新(upstart(文档数组?
基本上摆脱了这个伪代码示例中的for循环:
for user in users {
db.users.replaceOne(
{ "name" : user.name },
user,
{ "upsert": true }
}
更新许多文档只记录以下情况,即所有文档都以相同的方式更新:
db.collection.updateMany(
<query>,
{ $set: { status: "D" }, $inc: { quantity: 2 } },
...
)
我正在尝试更新(追加(一系列文档,其中每个文档都有自己的一组替换字段:
updateOptions := options.UpdateOptions{}
updateOptions.SetUpsert(true)
updateOptions.SetBypassDocumentValidation(false)
_, error := collection.Col.UpdateMany(ctx, bson.M{"name": bson.M{"$in": names}}, bson.M{"$set": users}, &updateOptions)
其中用户是一系列文档:
[
{ "name": "A", ...further fields},
{ "name": "B", ...further fields},
...
]
显然,$set
不能用于这种情况,因为我收到以下错误:批量写入*v1.UserCollection(FailedToParse(Modifiers对字段进行操作时出错,但我们找到了类型数组。
非常感谢您的帮助!
您可以使用Collection.BulkWrite()
。
由于您希望以不同的方式更新每个文档,因此必须为每个文档更新准备不同的mongo.WriteModel
。
您可以使用mongo.ReplaceOneModel
来替换单个文档。你可以这样构建它们:
wm := make([]mongo.WriteModel, len(users)
for i, user := range users {
wm[i] = mongo.NewReplaceOneModel().
SetUpsert(true).
SetFilter(bson.M{"name": user.name}).
SetReplacement(user)
}
你可以用一个这样的调用来执行所有的替换:
res, err := coll.BulkWrite(ctx, wm)
是的,这里我们也有一个循环,但那就是准备我们想要执行的写任务。所有这些都用单个调用发送到数据库;免费的";尽可能并行执行。这可能比单独为每个文档调用Collection.ReplaceOne()
要快得多。