dongzhenge2014 2017-01-28 08:02
浏览 1139
已采纳

在插入带有时间的文档时设置默认日期。时间字段

In mongoose(node.js) I can define a model schema with a default Date.now like so:

...
type: Date,
default: Date.now
...

How do I achieve the same without having to insert the time.Time every time I create a document with mgo?

type User struct {
    CreatedAt   time.Time `json:"created_at" bson:"created_at"` // Make this field filled automatically with time.Now() every time a document of this `struct` is inserted
}
  • 写回答

1条回答 默认 最新

  • douci2516 2017-02-20 12:10
    关注

    In Go you can't define default values for fields, they will always be the zero-value of their type when a new struct value is created (unless you use a composite literal where you can give a different value explicitly).

    So one option would be to create a constructor-like function NewUser() which would set this field, and use always this function to create new users:

    func NewUser() *User {
        return &User{
            CreatedAt: time.Now(),
        }
    }
    

    Of course this can't be forced, and also this will hold the timestamp of the User struct value creation and not when it is saved.

    Another, better approach is to use a custom marshaling logic.

    You can write custom marshaling logic by implementing bson.Getter. GetBSON() is responsible to provide a value that will actually be saved. We want the same User instance to be saved, just its CreatedAt field set prior:

    type User struct {
        CreatedAt time.Time `json:"created_at" bson:"created_at"`
    }
    
    func (u *User) GetBSON() (interface{}, error) {
        u.CreatedAt = time.Now()
        type my *User
        return my(u), nil
    }
    

    Note that a new my type is created and returned. The reason for this is to avoid stack overflow. Simply returning a value of type *User is bad, because it implements bson.Getter, so GetBSON() would get called endlessly. The new my type does not have this method, so endless "recursion" does not happen (the type keyword creates a new type, and it does not "inherit" methods of the underlying type).

    Note that this solution will also overwrite (re-set) the CreatedAt field) even if you just want to re-save a User. So we should add a check whether the CreatedAt field is filled, and only set it if it's the zero value:

    func (u *User) GetBSON() (interface{}, error) {
        if u.CreatedAt.IsZero() {
            u.CreatedAt = time.Now()
        }
        type my *User
        return my(u), nil
    }
    

    Also see related / similar question: Accesing MongoDB from Go

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?