【问题标题】:Set default date when inserting document with time.Time field插入带有 date.Time 字段的文档时设置默认日期
【发布时间】:2018-05-31 17:20:07
【问题描述】:

mongoose(node.js) 中,我可以使用默认的Date.now 定义模型架构,如下所示:

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

如何在每次使用mgo 创建文档时不必插入time.Time 来实现相同的目标?

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
}

【问题讨论】:

    标签: mongodb go struct time mgo


    【解决方案1】:

    在 Go 中,您不能为字段定义默认值,当创建新的结构值时,它们将始终是其类型的 zero-value(除非您使用 composite literal ,您可以显式地给出不同的值) .

    因此,一种选择是创建一个类似构造函数的函数NewUser(),它会设置此字段,并始终使用此函数来创建新用户:

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

    当然这不能强制,而且这将保存User结构值创建的时间戳,而不是保存时的时间戳。

    另一种更好的方法是使用自定义封送逻辑。

    您可以通过实现bson.Getter 来编写自定义封送逻辑。 GetBSON() 负责提供一个实际保存的值。我们希望保存相同的 User 实例,只是之前设置的 CreatedAt 字段:

    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
    }
    

    请注意,创建并返回了一个新的my 类型。这样做的原因是为了避免堆栈溢出。简单地返回一个*User 类型的值是不好的,因为它实现了bson.Getter,所以GetBSON() 会被无休止地调用。新的my 类型没有这个方法,所以不会发生无休止的“递归”(type 关键字创建了一个新类型,它不会“继承”底层类型的方法)。

    请注意,即使您只想重新保存 User,此解决方案也会覆盖(重新设置)CreatedAt 字段)。所以我们应该添加一个检查CreatedAt字段是否被填充,并且只有当它是零值时才设置它:

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

    另见相关/类似问题:Accesing MongoDB from Go

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-19
      • 2013-12-14
      • 2020-10-02
      • 1970-01-01
      • 1970-01-01
      • 2019-03-28
      相关资源
      最近更新 更多