Sok*_*edu 4 time go mongodb mgo
我有两个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
Run Code Online (Sandbox Code Playgroud)
每次我得到Date(-62135596800000)而不是null,即使我检索数据并将其挂起而不进行修改.
在Go中time.Time是一个没有nil值的结构.它具有零值(所有结构字段的值均为零),但此零值对应MongoDB ISODate("0001-01-01T00:00:00Z")而不是MongoDB null值.
如果您的字段是类型time.Time,则无法为其设置任何值以结束MongoDB null值.
最简单的解决方案是使用类型指针的字段time.Time,即*time.Time.如果您将此字段留下或设置为Go nil,它将null以MongoDB 结尾.
如果你不能或不想使用*time.Time,仍然有一个"解决方法":声明2个字段,一个是你的"常规" time.Time类型,并使用struct标签从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
}
Run Code Online (Sandbox Code Playgroud)
说明:
User.CreatedAt保存time.Time您可以使用的值(读/写).此字段从MongoDB中排除.
有一个指针User.PCreatedAt字段映射到createdMongoDB中的属性.
当a User被封送(保存到MongoDB)时,GetBSON()被调用.如果CreatedAt是零值,设置PCreatedAt到nil这将最终成为null在MongoDB中.否则设置/使用非零时间戳.
当a User被解组(从MongoDB加载)时,SetBSON()被调用.此检查,如果PCreatedAt是nil(其对应于MongoDB的null),并且如果是,则设置CreatedAt到它的零值.Else使用从MongoDB检索的时间戳.
相关/类似问题: