I’m migration our app from mgo to the official mongo go driver, but I’m stuck with the mgo SetBSON migration, this is my old code and I don’t know how to do this using the new driver:
type MyStruct struct {
ID primitive.ObjectID `bson:"_id"`
Ends time.Time `bson:"ends"`
}
func (st *MyStruct) SetBSON(raw bson.Raw) error {
decoded := new(struct {
ID primitive.ObjectID `bson:"_id"`
Ends string `bson:"ends"`
})
bsonErr := raw.Unmarshal(decoded)
if bsonErr != nil {
return bsonErr
}
const dateFormat = "2006-01-02"
end, endErr := time.ParseInLocation(dateFormat, decoded.Ends, constants.NYCLoc)
if endErr != nil {
return endErr
}
st.ID = decoded.ID
st.Ends = time.Date(ey, em, ed, 23, 59, 0, 0, constants.NYCLoc)
return nil
}
The core is, we have a struct that in mongo stores the “end” field as a string that looks like “20200402”. When the driver reads the bson from mongo, I need to decode the struct and convert the string value from the field “end” into a time.Time Go type.
I hope I can avoid having to create a new custom “field” type for the end mongo field, because the app assumes a time.Time all over.
Thanks
Hi @Diego_Medina,
You can do this using the UnmarshalBSON
hook for the driver. This is similar to the UnmarshalJSON
hook in the encoding/json
library. I wrote up an example of this in Go Playground - The Go Programming Language. It’s worth noting that version 1.3.0 of the driver introduced a custom BSON registry to mimic parts of mgo BSON behavior to mitigate BSON issues for users when migrating to the official driver. This registry supports GetBSON
/SetBSON
. You can see documentation for that at mgocompat package - go.mongodb.org/mongo-driver/bson/mgocompat - Go Packages.
2 Likes
Thanks you! your example was just what I needed.
I was trying to understand why not use the bsoncodec package - go.mongodb.org/mongo-driver/bson/bsoncodec - Go Packages.
Is this what you mean by
It’s worth noting that version 1.3.0 of the driver introduced a custom BSON registry
@Yehuda_Makarov You can use the bsoncodec package and write a custom codec for this use case, but implementing the bson.Unmarshaler
interface works just as well.
Version 1.3.0 of the driver introduced a new mgocompat
package that provides a custom BSON registry (mgocompat.Registry
) to mimic some of mgo’s BSON behavior. This includes adding support for GetBSON
and SetBSON
methods. You can see more details about it at mgocompat package - go.mongodb.org/mongo-driver/bson/mgocompat - Go Packages. Search for Setter
on that page to see how the SetBSON
method should be implemented. If you choose to use this registry, you can enable it for a Client
as follows:
opts := options.Client().SetRegistry(mgocompat.Registry)
client, err := mongo.Connect(ctx, opts)
// handle err, defer Disconnect(), etc
Feel free to add another comment here or open a new question on these forums if you have any follow-up questions about the new registry.
– Divjot
2 Likes