亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用過濾器中的值更新文檔

使用過濾器中的值更新文檔

Go
小怪獸愛吃肉 2022-05-18 13:49:21
我在 MongoDB 中有一個具有以下結構的集合:{  "userId": String,  "refs": Set<String>}我需要用這些文檔更新集合。我想為refsfilter 中的用戶添加一個新字符串$in。但是,如果用戶不存在,我需要“更新”他。在代碼(golang)中,它看起來像這樣:filter := bson.M{    "userId": bson.M{        "$in:": tokens // tokens is []string    }}update := bson.M{    "$addToSet": bson.M{        "refs": newReference    }}ctx, _ := newDbOperationContext()_, err := driver.UpdateMany(ctx, filter, update)因此,對于現有用戶來說它工作正常,添加了參考。但是,對于不存在的用戶,什么都不會發生。我設置了driver.UpdateMany(bson, bson, opts...)opts to options.UpdateOptions.SetUpsert(true)",但結果我得到了一個沒有 userId 的文檔:{  "_id": ObjectId("..."),  "refs": ["new_reference"]}所以,我的問題是,如何用userId字段更新新值。規模就像要更新 2*10^6 個用戶,所以我想使用批處理請求來做到這一點。我認為,使用“一個一個”創建并更新他不是一個選項。謝謝你的支持!
查看完整描述

3 回答

?
LEATH

TA貢獻1936條經驗 獲得超7個贊

根據之前在 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)


查看完整回答
反對 回復 2022-05-18
?
catspeake

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 模型一起使用。


查看完整回答
反對 回復 2022-05-18
?
手掌心

TA貢獻1942條經驗 獲得超3個贊

在 upsert 的情況下,如果文檔不存在,那么只有查詢的更新部分會插入到數據庫中。所以這就是為什么你的輸出是這樣的。你可以在這里看到。


查看完整回答
反對 回復 2022-05-18
  • 3 回答
  • 0 關注
  • 130 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號