In our code base we have a function which merges two structs , something like below .
func CombineStruct(s1 interface{}, s2 interface{}) error {
data, err := json.Marshal(s1)
if err != nil {
return err
}
return json.Unmarshal(data, s2)
}
We use the above func to combine two structs something like below .
m := model.SomeModel{}
CombineStruct(someStruct, &m)
//above line merges two structs
Also currently all our structs has only json
tags not bson
tags yet, should we need to add bson
tags in all the places ?
for ex :
type someStruct struct {
Field1 string `json:"field1"`
Field2 string `json:"field2"`
Field3 interface{} `json:"field2"`
}
In the above someStruct
we have fields of type interface too!
Now the issue that i'm facing is wherever we combine the struct I see those object data in mongoDB
as array of key-value
pair something like below :
"studentDetails" : [
{
"Key" : "Details",
"Value" : [
[
{
"Key" : "Name",
"Value" : "Bob"
},
{
"Value" : "21",
"Key" : "Age"
}
]
]
},
{
"Key" : "Enrolled",
"Value" : false
}
],
But I want this to be displayed like something like below . Not like key-value
pair.
"studentDetails" : {
"Details" : [
{
"name" : "serverdr",
"age" : 21
},
{
"Enrolled" : false
}
],
It was displaying objects like above way in our old global sing mgo driver .But using the new go-mongo driver when we combine two structs using the CombineStruct()
function it displays
as array of key value pair.
I tried something like below and that worked like a charm :)
So basically what's the problem is that the mongo-driver defaults to unmarshalling as bson.D
for structs of type interface{}
where as mgo
mgo-driver defaults to bson.M
.
So we will have to add the below code while trying to establish connection with mongo-db
, SetRegistry()
options as clientOpts
To map the old mgo behavior, so that mongo-driver
defaults to bson.M
while unmarshalling structs of type interface{}
, and this should not display the values back as key-value
pair
tM := reflect.TypeOf(bson.M{})
reg := bson.NewRegistryBuilder().RegisterTypeMapEntry(bsontype.EmbeddedDocument, tM).Build()
clientOpts := options.Client().ApplyURI(SOMEURI).SetAuth(authVal).SetRegistry(reg)
client, err := mongo.Connect(ctx, clientOpts)