Home > Blockchain >  MongoDB Golang Driver only update fields were provided value is not empty
MongoDB Golang Driver only update fields were provided value is not empty

Time:01-31

I want to create a function to update a specific document in MongoDB by it's id but only update the fields if the new provided value is not the Go default.

This is the document struct which I store in MongoDB:

type User struct {
    ID          primitive.ObjectID `json:"id"                    bson:"_id,omitempty"`
    Username    string             `json:"username"              bson:"username"`
    FirstName   string             `json:"firstName"             bson:"first_name"`
    LastName    string             `json:"lastName,omitempty"    bson:"last_name,omitempty"`
    Email       string             `json:"email"                 bson:"email"`
    Password    string             `json:"password,omitempty"    bson:"password"`
    PhoneNumber string             `json:"phoneNumber,omitempty" bson:"phone_number,omitempty"`
    Picture     string             `json:"picture,omitempty"     bson:"picture,omitempty"`
    Role        Role               `json:"role"                  bson:"role"`
}

My update function gets the id of the user document to update and a user struct with only the fields provided which should get updated. So if only the username should get updated all other fields in the provided user struct will have their default value.
I now need to first check if for example the new username is not empty and only then include it on the new update document.

This is how I would solve it in javsacript. Is there a similar solution for Go?

{
  ...(username && { username: username }),
  ...(email && { email: email }),
  ...(firstname && { firstname: firstname }),
  ...(lastname && { lastname: lastname }),
  ...(phone && { phone: phone }),
  ...(picture && { picture: picture }),
},

This is my Update function:

func (us *userQuery) Update(userId string, u datastruct.User) (*datastruct.User, error) {
    userCollection := DB.Collection(datastruct.UserCollectionName)

    ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
    defer cancel()

    _id, err := primitive.ObjectIDFromHex(userId)
    if err != nil {
        return nil, err
    }

    update := bson.D{{
        Key: "$set",
        Value: bson.D{
            {Key: "username", Value: u.Username}, // only include a field if provided value is not the default
            {Key: "firstName", Value: u.FirstName},
            {Key: "lastName", Value: u.LastName},
            {Key: "email", Value: u.Email},
            {Key: "password", Value: u.Password},
            {Key: "phoneNumber", Value: u.PhoneNumber},
            {Key: "picture", Value: u.Picture},
        },
    }}

    var result datastruct.User
    res, err := userCollection.UpdateByID(
        ctx,
        _id,
        update,
    )
    if err != nil {
        return nil, err
    }

    return &result, nil
}

CodePudding user response:

You have to build the update clause dynamically:

value:=bson.M{}
if len(u.UserName)!=0 {
  value["username"]=u.UserName
}
if len(u.FirstName)!=0 {
  value["firstName"]=u.FirstName
}
...
if len(value)>0 { // Is there anything to update?
  res, err := userCollection.UpdateByID(
          ctx,
          _id,
          bson.M{"$set":value})
}
  •  Tags:  
  • Related