如何使用 mongo go driver 而不是 Date(-62135596800000) 为日期字段分配空值
How can I assign a null value to date field using mongo go driver instead of Date(-62135596800000)
我有两台 MongoDB 服务器。从一个我使用 mongo go 驱动程序接收数据。接收到的数据有一个日期字段,该字段始终为 null
。然后在我的代码中,我可能会也可能不会将其更改为其他日期或将其保留为 null
并将接收到的数据发送到其他服务器。
问题是当我post数据时,时间字段变成了
Date(-62135596800000) instead of 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,即使我检索数据并在不修改的情况下更新它也是如此。
在 Go 中 time.Time
是一个不能有 nil
值的结构。它有一个零值(这是所有具有零值的结构字段),但是这个零值对应于 MongoDB ISODate("0001-01-01T00:00:00Z")
而不是 MongoDB null
值。
如果您的字段是 time.Time
类型,您不能为其设置任何值以结束 MongoDB null
值。
最简单的解决方案是使用指向 time.Time
的指针类型的字段,即 *time.Time
。如果您将此字段保留或设置为 Go nil
,它将在 MongoDB 中以 null
结束。
如果你不能或不想使用*time.Time
,还有一个"workaround":声明2个字段,一个是你的"regular" 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
设置为其零值。否则使用从 MongoDB.
检索到的时间戳
相关/类似问题:
Accesing MongoDB from Go
mongodb 文档
行为
在内部,Date 对象存储为 64 位整数,表示自 Unix 纪元(1970 年 1 月 1 日)以来的毫秒数,这导致可表示的日期范围为过去和未来约 2.9 亿年
我有两台 MongoDB 服务器。从一个我使用 mongo go 驱动程序接收数据。接收到的数据有一个日期字段,该字段始终为 null
。然后在我的代码中,我可能会也可能不会将其更改为其他日期或将其保留为 null
并将接收到的数据发送到其他服务器。
问题是当我post数据时,时间字段变成了
Date(-62135596800000) instead of 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,即使我检索数据并在不修改的情况下更新它也是如此。
在 Go 中 time.Time
是一个不能有 nil
值的结构。它有一个零值(这是所有具有零值的结构字段),但是这个零值对应于 MongoDB ISODate("0001-01-01T00:00:00Z")
而不是 MongoDB null
值。
如果您的字段是 time.Time
类型,您不能为其设置任何值以结束 MongoDB null
值。
最简单的解决方案是使用指向 time.Time
的指针类型的字段,即 *time.Time
。如果您将此字段保留或设置为 Go nil
,它将在 MongoDB 中以 null
结束。
如果你不能或不想使用*time.Time
,还有一个"workaround":声明2个字段,一个是你的"regular" 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
设置为其零值。否则使用从 MongoDB.
相关/类似问题:
Accesing MongoDB from Go
mongodb 文档
行为
在内部,Date 对象存储为 64 位整数,表示自 Unix 纪元(1970 年 1 月 1 日)以来的毫秒数,这导致可表示的日期范围为过去和未来约 2.9 亿年