我有两台MongoDB服务器。从一个我使用mongo go driver接收数据。收到的数据有一个日期字段,始终为null
。然后在我的代码中,我可能会或可能不会将其更改为其他日期或将其保留为null
并将接收的数据放入其他服务器。
问题在于,当我发布数据时,时间字段变为
日期(-62135596800000)而不是null。
我尝试分配time.Time{}
,下面的代码也没有解决问题。
t, err := time.Parse("2006-01-02T15:04:05Z", "0001-01-01T00:00:01Z")
if err != nil {
fmt.Println(err)
}
retrieved[i].SessionEndedDateUTC = t
每次我得到Date(-62135596800000)
而不是null,即使我检索数据并将其挂起而不进行修改。
答案 0 :(得分:5)
在Go time.Time
中,结构不能具有nil
值。它具有零值(所有结构字段的值都为零),但此零值对应MongoDB ISODate("0001-01-01T00:00:00Z")
,而不是MongoDB null
值。
如果您的字段属于time.Time
类型,则无法为其设置任何值以结束MongoDB null
值。
最简单的解决方案是使用指向time.Time
的类型指针字段,即*time.Time
。如果您将此字段留下或设置为转到nil
,它将在MongoDB中以null
结尾。
如果您不能或不想使用*time.Time
,仍然有一个"解决方法":声明2个字段,一个是您的"定期" time.Time
类型,并使用struct tag将其从MongoDB中排除。并添加另一个*time.Time
类型的字段,并将其映射到MongoDB。并编写一个自定义编组/解编逻辑,当编组时会根据原始文件更新这个额外字段,或者在解组时根据额外字段设置原始文件。
这是一个示例:
type User struct {
CreatedAt time.Time `bson:"-"`
PCreatedAt *time.Time `bson:"created"`
}
func (u *User) GetBSON() (interface{}, error) {
if u.CreatedAt.IsZero() {
u.PCreatedAt = nil
} else {
u.PCreatedAt = &u.CreatedAt
}
return u, nil
}
func (u *User) SetBSON(raw bson.Raw) (err error) {
if err = raw.Unmarshal(u); err != nil {
return
}
if u.PCreatedAt == nil {
u.CreatedAt = time.Time{}
} else {
u.CreatedAt = *u.PCreatedAt
}
return
}
<强>解释强>
User.CreatedAt
包含您可以使用的time.Time
值(读/写)。此字段不包含在MongoDB中。
指针User.PCreatedAt
字段映射到MongoDB中的created
属性。
当封送User
(保存到MongoDB)时,会调用GetBSON()
。如果CreatedAt
为零值,则将PCreatedAt
设置为nil
,这将在MongoDB中以null
结尾。否则设置/使用非零时间戳。
当User
被解组(从MongoDB加载)时,会调用SetBSON()
。这将检查PCreatedAt
是nil
(对应于MongoDB null
),如果是,则将CreatedAt
设置为零值。 Else使用从MongoDB检索的时间戳。
相关/类似问题:
Set default date when inserting document with time.Time field
答案 1 :(得分:0)
mongodb doc
行为
在内部,Date对象存储为64位整数,表示自Unix纪元(1970年1月1日)以来的毫秒数,这导致过去和未来的可表示日期范围约为2.9亿年