3 回答
TA贡献1936条经验 获得超6个赞
根据之前在 SO 中的问题,例如这个和另一个,似乎不可能upserts仅使用$in运算符执行多个,因为它只会插入一个文档(与过滤器匹配的那个):
如果没有文档与查询条件匹配,则 db.collection.update() 插入单个文档。
因此,正如@Kartavya 所提到的,最好的方法是使用BulkWrite.
为此,您需要为每个用户附加一个 upsert 操作(= WriteModel)tokens作为过滤器,并且您可以使用相同的$addToSet更新操作:
tokens := [...]string{"userId1", "userId3"}
newRef := "refXXXXXXX"
// all docs can use the same $addToSet update operation
updateOp := bson.D{{"$addToSet", bson.D{{"refs", newRef}}}}
// we'll append one update for each userId in tokens as a filter
upserts := []mongo.WriteModel{}
for _, t := range tokens {
upserts = append(
upserts,
mongo.NewUpdateOneModel().SetFilter(bson.D{{"userId", t}}).SetUpdate(updateOp).SetUpsert(true))
}
opts := options.BulkWrite().SetOrdered(false)
res, err := col.BulkWrite(context.TODO(), upserts, opts)
if err != nil {
log.Fatal(err)
}
fmt.Println(res)
TA贡献1111条经验 获得超0个赞
查看您的用例,我认为最好的解决方案如下:
由于您的规模很大并且希望进行批量请求,因此最好使用 BulkWrite : db.collection.bulkWrite() 方法提供了执行批量插入、更新和删除操作的能力。示例:https ://godoc.org/go.mongodb.org/mongo-driver/mongo#example-Collection-BulkWrite
这使用 UpdateOne 模型,但它也支持 UpdateMany 模型。它也是 SetUpsert(true) 的一个功能 现在对于 _id 字段:您更新/更新的文档应该具有 _id 字段,以便新文档具有该 _id 字段,否则 mongoDb 会在插入文档时自动生成一个 _id 字段,如果您的 upsert 文档有没有 _id 字段
我认为,在您的文档中包含 _id 字段不会很痛苦,这样您的问题就解决了。
关于规模,我建议将 BulkWrite 与 UpdateOne 或 UpdateMany 模型一起使用。
- 3 回答
- 0 关注
- 100 浏览
添加回答
举报