如何使用mongo go驱动程序而不是Date(-62135596800000)将空值分配给日期字段

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,即使我检索数据并将其挂起而不进行修改.

icz*_*cza 5

在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是零值,设置PCreatedAtnil这将最终成为null在MongoDB中.否则设置/使用非零时间戳.

当a User被解组(从MongoDB加载)时,SetBSON()被调用.此检查,如果PCreatedAtnil(其对应于MongoDB的null),并且如果是,则设置CreatedAt到它的零值.Else使用从MongoDB检索的时间戳.

相关/类似问题:

使用time.Time字段插入文档时设置默认日期

从Go访问MongoDB