MongoDB更新文档数组并替换为替换文档数组



是否可以通过替换字段(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()要快得多。

最新更新