Search code examples
mongodbgostructmongo-go

Autofill created_at and updated_at in golang struct while pushing into mongodb


type User struct {
    ID           primitive.ObjectID `bson:"_id,omitempty"`
    CreatedAt    time.Time          `bson:"created_at"`
    UpdatedAt    time.Time          `bson:"updated_at"`
    Name         string             `bson:"name"`
}

user := User{Name: "username"}

client.Database("db").Collection("collection").InsertOne(context.Background(), user)

How to use automated created_at and updated_at in the above code with mongodb(mongodb driver only) in golang? Currently it will set zero time(0001-01-01T00:00:00.000+00:00) for created_at and updated_at.


Solution

  • The MongoDB server does not support this.

    You may implement a custom marshaler in which you may update these fields to your liking. Implement bson.Marshaler, and your MarshalBSON() function will be called when you save values of your *User type.

    This is how it would look like:

    func (u *User) MarshalBSON() ([]byte, error) {
        if u.CreatedAt.IsZero() {
            u.CreatedAt = time.Now()
        }
        u.UpdatedAt = time.Now()
        
        type my User
        return bson.Marshal((*my)(u))
    }
    

    Note the method has pointer receiver, so use a pointer to your value:

    user := &User{Name: "username"}
    
    
    c := client.Database("db").Collection("collection")
    if _, err := c.InsertOne(context.Background(), user); err != nil {
        // handle error
    }
    

    The purpose of the my type is to avoid stack overflow.