Skip to content

Update

UpdateOne

UpdateOne(ctx context.Context, filter interface{}, updateOrDoc interface{}, opts ...*options.UpdateOptions) (modifiedCount int64, err error)

go
modifiedCount, err := db.Users.UpdateOne(ctx, bson.M{"age": 6}, &User{Name: "gggggo"})
if err != nil {
    fmt.Println(err)
}
fmt.Println(modifiedCount) // 1

TIP

When updateOrDoc is of the same type as the model, the hooks BeforeUpdate and AfterUpdate will be triggered. However, the modifiedCount may not be accurate in this case.

Details
go
if doc, ok := updateOrDoc.(T); ok {
    doc.BeforeUpdate(ctx)
    defer doc.AfterUpdate(ctx)
    res, err := r.collection.UpdateOne(ctx, filter, bson.M{"$set": doc}, opts...)
    return res.ModifiedCount, err
}

If you don't use the model as the update data, you need to manually add bson.M{"$set": doc}.

go
modifiedCount, err := db.Users.UpdateOne(ctx, bson.M{"age": 6}, bson.M{"$set": bson.M{"name": "gooooo"}})
if err != nil {
    fmt.Println(err)
}
fmt.Println(modifiedCount) // 0

TIP

This design allows the use of more operators! For example:

NameDescription
$currentDateSets the value of a field to current date, either as a Date or a Timestamp.
$incIncrements the value of the field by the specified amount.
$minOnly updates the field if the specified value is less than the existing field value.
$maxOnly updates the field if the specified value is greater than the existing field value.
$mulMultiplies the value of the field by the specified amount.
$renameRenames a field.
$setSets the value of a field in a document.
$setOnInsertSets the value of a field if an update results in an insert of a document. Has no effect on update operations that modify existing documents.
$unsetRemoves the specified field from a document.

UpdateMany

UpdateMany(ctx context.Context, filter interface{}, updateOrDoc interface{}, opts ...*options.UpdateOptions) (modifiedCount int64, err error)

go
modifiedCount, err := db.Users.UpdateMany(ctx, bson.M{"age": 2}, &User{Name: "gggggo"})
if err != nil {
    fmt.Println(err)
}
fmt.Println(modifiedCount)

TIP

When updateOrDoc is of the same type as the model, the hooks BeforeUpdate and AfterUpdate will be triggered. However, the modifiedCount may not be accurate in this case.

UpdateByID

UpdateByID(ctx context.Context, id interface{}, updateOrDoc interface{}, opts ...*options.UpdateOptions) (modifiedCount int64, err error)

go
modifiedCount, err := db.Users.UpdateByID(ctx, user.ID, bson.M{"$set": bson.M{"name": "gooooo"}})
if err != nil {
    fmt.Println(err)
}
fmt.Println(modifiedCount)

TIP

When updateOrDoc is of the same type as the model, the hooks BeforeUpdate and AfterUpdate will be triggered. However, the modifiedCount may not be accurate in this case.

FindOneAndUpdate

FindOneAndUpdate(ctx context.Context, filter interface{}, updateOrDoc interface{}, opts ...*options.FindOneAndUpdateOptions) (T, error)

go
user, err := db.Users.FindOneAndUpdate(ctx, bson.M{"age": 6}, bson.M{"$set": bson.M{"name": "gooooo"}})
if err != nil {
    fmt.Println(err)
}
fmt.Println(user.ID)

TIP

When updateOrDoc is of the same type as the model, the hooks BeforeUpdate and AfterUpdate will be triggered, while AfterFind has no such restriction.

Released under the MIT License.