Search code examples
mongodbgogo-fiber

MongoDB GO driver overwriting existing data


I am using GO-FIBER and using MONGODB MongoDB Go Driver. I want to update only the fields given by the body. But it is overwriting the data.

I just updated the name Entire document for overwritten

func UpdateOneUser(c *fiber.Ctx) error {
    params := c.Params("id")
    body := new(models.User)
    
    id, err := primitive.ObjectIDFromHex(params)
    if err != nil {
        return c.Status(500).SendString("invalid onjectid")
    }

    if err := c.BodyParser(&body); err != nil {
        return c.Status(400).SendString("invalid body")
    }
    
    filter := bson.M{"_id": id}
    update := bson.M{"$set": bson.M{
        "name": body.Name,
        "username": body.Username,
        "first_name": body.FirstName,
        "last_name": body.LastName,
        "email": body.Email,
        "phone_number": body.PhoneNumber,
        "contry": body.Contry,
        "age": body.Age,
        "child_accounts": body.ChildAccounts,
        "groups": body.Groups,

    }}
    
    result, err := db.User.UpdateOne(context.Background(), filter, update)
    if err != nil {
        return c.Status(500).SendString("user not found")
    }
    fmt.Println(result)

    return c.JSON(body)

}

If this is how the driver works then tell me a better way to update my documents.


Solution

  • The $set operator will overwrite all the fields you specify, so you have to build the update statement selectively:

    fields:=bson.M{}
    if body.Name!="" {
       fields["name"]=body.Name
    }
    ...
    update:=bson.M{"$set":fields}
    

    You can use some shortcuts:

    fields:=bson.M{}
    add:=func(key,value string) {
       if value!="" {
          fields[key]=value
       }
    }
    add("name",body.Name)
    add("userName",body.UserName)