jsonmongodbgodriverbson

MongoDB document returns array of key value pair in go mongo-driver


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.


Solution

  • 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)