In the community driven Mongo driver for Go, i.e. Mgo, we can use the Apply
API call to run MongoDB queries involving $set
or $inc
. An example of this use-case in Mgo is as follows:
change := mgo.Change{
Update: bson.M{"$set": bson.M{"phone": "+55 53 8402 8510"}},
ReturnNew: true,
}
_, err = MongoSession.DB("test").C("people").Find(bson.M{"_id": a}).Apply(change, &result)
Quoting the official documentation for this API call:
Apply runs the findAndModify MongoDB command, which allows updating, upserting or removing a document matching a query and atomically returning either the old version (the default) or the new version of the document (when ReturnNew is true).
I am currently working on porting a project from Mgo to the official Mongo Go driver. However, I am unable to find any method that runs the findAndModify command to achieve a similar use-case. For replacing the Apply API with a relevant method from the official driver, what would be the recommended approach?
I have considered examining the query under 'Update' in the existing code, and manually using the Find/Update/Replace methods provided in the official driver. But, would there be any better way to do the same?
I was able to solve this using the FindOneAndUpdate API.
It internally uses FindAndModify
, even though it is not explicitly mentioned in the documentations. Code I used to emulate this feature of Mgo in Go's Mongo Driver is as follows:
MongoSession, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017"))
if err != nil {
panic(err)
}
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
err = MongoSession.Connect(ctx)
collection := MongoSession.Database("test").Collection("people")
a, err := primitive.ObjectIDFromHex("XXXXXXXXXX") //hiding hex value
b := collection.FindOneAndUpdate(ctx, bson.M{"_id": a}, bson.M{"$set": bson.M{"phone": "Replacing using the query"}})
Edit (29/02/20): It looks like after this answer, the MongoDB Engineers have updated the documentation about the MongoDB functionality being used. The documentation now states that FindOneAndUpdate
uses the findAndModify
operation.