什么?
試圖從 mongo 檔案中的物件陣列中洗掉一個元素。
我使用: go version go1.17.1 darwin/amd64;go.mongodb.org/mongo-driver v 1.8.4;MongoDB 5.0.6 企業版
函式的簡化版本,一切都盡可能簡單:
func (r *Repo) UpdateModelByID(ctx context.Context, id string) error {
objID, err := primitive.ObjectIDFromHex(id)
// I actually handle err here, it's nil
filter := bson.D{{"_id", objID}}
update = bson.D{{
Key: "$pull",
Value: bson.E{
Key: "data",
Value: bson.E{
Key: "field_type",
Value: bson.E{
Key: "$in",
Value: []string{"field_type_1", "field_type_2"},
},
},
},
}}
log.Debugln("UPDATE", update)
result, err = cdm.getTemplatesCollection().UpdateOne(ctx, filter, update)
// I actually handle err here, it's nil
log.Debugf("RESULT_OF_UPDATE: % v", result)
}
預期的:
我提供的具有 id 的檔案將不再在陣列“data”中包含欄位“field_type”等于“field_type_1”或“field_type_2”的元素
得到:
DEBU[0023] UPDATE [{$pull {data {field_type {$in [field_type_1, field_type_2]}}}}]
DEBU[0023] RESULT_OF_UPDATE: &{MatchedCount:1 ModifiedCount:0 UpsertedCount:0 UpsertedID:<nil>}
通過 mongosh 執行相同的命令:
db.templates.updateOne(
{ _id: ObjectId("6228a89d621d19a2f7977d2f") },
{ $pull: { data: {field_type: {$in: ["field_type_1", "field_type_2"]}}}
}
)
{ acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 1,
upsertedCount: 0 }
并且 elem-s 從陣列中消失了。
為什么會這樣?
我確實注意到本機查詢有單個大括號(只是一個物件),而 Go 代碼使用 bson.D,它在技術上是這些相同物件的陣列 (bson.E) -> [{}]。
我嘗試更改 mongosh 命令來測驗:
db.templates.updateOne(
{ _id: ObjectId("6228a89d621d19a2f7977d2f") },
[{ $pull: { data: {field_type: {$in: ["field_type_1", "field_type_2"]}}}
}]
)
MongoServerError: Unrecognized pipeline stage name: '$pull'
在 Go 中,我嘗試使用 bson.E 而不是 bson.D(盡管根據檔案建議將后者用于命令)并得到了這個:
DEBU[0030] UPDATE {$pull {data {field_type {$in [field_type_1, field_type_2]}}}}
ERRO[0030] cannot update model by id: update document must contain key beginning with '$' method=UpdateModelByID templateId=6228a89d621d19a2f7977d2f
uj5u.com熱心網友回復:
bson.D對檔案建模,具有鍵值對的有序串列,其中鍵是屬性名稱,值是屬性的值。
因此,如果您打算使用bson.D對檔案進行建模,則始終必須bson.D在等效的 shell 命令中有檔案的地方撰寫復合文字。
因此,您的update檔案必須如下所示:
update := bson.D{{
Key: "$pull", Value: bson.D{{
Key: "data", Value: bson.D{{
Key: "field_type", Value: bson.D{{
Key: "$in", Value: []string{"field_type_1", "field_type_2"},
}}},
}},
}},
}
如果您從復合文字中省略命名欄位,則會簡化為:
update := bson.D{
{"$pull", bson.D{{
"data", bson.D{{
"field_type", bson.D{{
"$in", []string{"field_type_1", "field_type_2"},
}}},
}},
}},
}
是的,有點丑。請注意,如果元素的順序無關緊要,使用bson.M值來定義檔案會更容易(它是一張地圖)。有關詳細資訊,請參閱bson.D 與 bson.M 查找查詢
您update可能看起來像這樣定義的bson.M:
update := bson.M{
"$pull": bson.M{
"data": bson.M{
"field_type": bson.M{
"$in": []string{"field_type_1", "field_type_2"},
},
},
},
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/440587.html
