为了账号安全,请及时绑定邮箱和手机立即绑定

如何用 Go 驱动程序替换 MongoDB 中的文档?

如何用 Go 驱动程序替换 MongoDB 中的文档?

Go
慕雪6442864 2022-07-11 10:19:25
我正在尝试使用mongodb/mongo-go-driver. 从其文档中,一个文档可以替换为:var coll *mongo.Collectionvar id primitive.ObjectID// find the document for which the _id field matches id and add a field called "location"// specify the Upsert option to insert a new document if a document matching the filter isn't foundopts := options.Replace().SetUpsert(true)filter := bson.D{{"_id", id}}replacement := bson.D{{"location", "NYC"}}result, err := coll.ReplaceOne(context.TODO(), filter, replacement, opts)if err != nil {    log.Fatal(err)}if result.MatchedCount != 0 {    fmt.Println("matched and replaced an existing document")    return}if result.UpsertedCount != 0 {    fmt.Printf("inserted a new document with ID %v\n", result.UpsertedID)}但是,如果我的字段超过 20 个怎么办。我想知道是否可以在不重新编写所有字段的情况下进行更新,我尝试了这样的方法:// Replacement structtype Input struct {    Name        *string `json:"name,omitempty" bson:"name,omitempty" validate:"required"`    Description *string `json:"description,omitempty" bson:"description,omitempty"`    Location    *string `json:"location,omitempty" bson:"location,omitempty"`}... oid, _ := primitive.ObjectIDFromHex(id) // because 'id' from request is stringfilter := bson.M{"_id", oid} // throws `[compiler] [E] missing key in map literal`//                      ^^^replacement := bson.D{{"$set", input}} // throws `composite literal uses unkeyed fields`//                             ^^^^^result, err := coll.ReplaceOne(context.TODO(), filter, replacement, opts)...但它会在过滤和替换时引发错误。如何正确替换整个文档?
查看完整描述

2 回答

?
12345678_0001

TA贡献1802条经验 获得超5个赞

bson.M是一个地图,所以如果你使用它,你必须写:bson.M{"_id": oid}. 查看复合文字 go 中缺少的类型和地图文字 go 中缺少的键

Andbson.D是一片结构体,所以如果你使用它,你应该写bson.D{{Key:"$set", Value: input}}. 省略字段名称不是编译器错误,它只是一个 go vet 警告。

现在开始更换。替换必须是文档本身,而不是使用$set(这不是更新而是替换)。有关参考,请参阅 MongoDBcollection.replaceOne()和驱动程序的文档Collection.ReplaceOne()::

替换参数必须是用于替换所选文档的文档。它不能为 nil,也不能包含任何更新运算符(https://docs.mongodb.com/manual/reference/operator/update/)。

所以这样做:

filter := bson.M{"_id": oid}
result, err := coll.ReplaceOne(context.TODO(), filter, input, opts)


查看完整回答
反对 回复 2022-07-11
?
梦里花落0921

TA贡献1772条经验 获得超6个赞

这是完整的代码。这将有助于读者理解代码流。


func UpdateFunction(echoCtx echo.Context) (error) {


//Web Section

    documentID := echoCtx.Param("id")   //Provided in URL


    var newObject myStruct

    err := echoCtx.Bind(&newObject)  // Json with updated values sent by web client mapped to struct


    ctx := echoCtx.Request().Context()


//Database Section

    database := db.Conn.Database("myDatabase")

    collection := database.Collection("myCollection")


    existingHexID, err := primitive.ObjectIDFromHex(documentID)


    if err != nil {

        fmt.Println("ObjectIDFromHex ERROR", err)

    } else {

        fmt.Println("ObjectIDFromHex:", existingHexID)

    }


    // Replacing OLD document with new using _id

    filter := bson.M{"_id": newDocumentID}

    result, err := collection.ReplaceOne(ctx, filter, newObject)


    if err != nil {

        log.Fatal(err)

    }


    fmt.Printf(

        "insert: %d, updated: %d, deleted: %d /n",

        result.MatchedCount,

        result.ModifiedCount,

        result.UpsertedCount,

    )


    return echoCtx.JSON(http.StatusOK, result.ModifiedCount)

}


查看完整回答
反对 回复 2022-07-11
  • 2 回答
  • 0 关注
  • 139 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信