猿问

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

我正在尝试使用mongodb/mongo-go-driver. 从其文档中,一个文档可以替换为:


var coll *mongo.Collection

var 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 found

opts := 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 struct

type 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 string

filter := 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)

...

但它会在过滤和替换时引发错误。如何正确替换整个文档?


慕雪6442864
浏览 174回答 2
2回答

12345678_0001

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)

梦里花落0921

这是完整的代码。这将有助于读者理解代码流。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)}
随时随地看视频慕课网APP

相关分类

Go
我要回答