partial update using mgo

eAbi picture eAbi · May 10, 2014 · Viewed 15.8k times · Source

I have the following problem. I need to convert a structure to map[string]interface{} in order to perform an update in database (using mgo as driver for mongodb).

Update

For partially updating a document in mongoDB, the (optimal) solution is to convert to a map and delete the unwanted fields. For converting from struct to map please refer to my other post


Original Post

I receive the data from client side javascript and write in the my struct model. But I don't want to change/update some fields and thus I need to convert my structure to a map[string]interface{} to delete the unwanted fields.

Converting the structure to json and then to map it's not ok because the field types are not preserved. For example, let the followin structure be an Image model:

type Image struct {
    Name string `json:name`
    Views int `json:views,string`
    Owner string `json:owner`
}

So far so good, but when I receive informations from client(i.e. javascript) the views field is a string. If I convert to a map the json input given from client, then the views field remains a string and the internal representation of this value is changed in database. So next time I read this image from database, the Views field is zeroed (because of it's string representation from database).

Thus I write the json input from client in structure (for proper conversion of Views variable). But the owner value shouldn't change (the one form database). So I need to convert again the structure to a map[string]interface{} and process that map before making the update in database.

Using the json package for this it's not an option, because the string tag from Views field will convert from int to string (when converting to map).

So far I've tried the following function for converting structure to map, and I use reflection package and am a noob with using it. Don't quite understand well the package.

I would be grateful if you would come up with some ideas. Thanks.

Answer

nvcnvn picture nvcnvn · May 10, 2014

The solution can be:
1. client json -> struct -> xml -> map -> database
2. Update partital with $set operator:

collection.Update(bson.M{"_id": id}, bson.M{"$set": bson.M{"name": "new Name"}})

Read more: http://docs.mongodb.org/manual/reference/operator/update/set/
3. Load the document that is going to be updated and store it in a tmp variable. Parse the user input to another variable. Overwrite the values you need to preserve before updating.