我使用Go访问MongoDB,如下所示:
var configRes *clientConfigData
err := clientDB.
C(clientConfigCollection).
Find(bson.M{}).
One(&configRes)
if err != nil {
return nil, errors.Wrap(err, "finding config collection")
}
哪里
type clientConfigData struct {
SMTPAssoc int `bson:"smtp_assoc"`
PlanType string `bson:"plan_type"`
EndDate string `bson:"end_date"`
}
现在,由于MongoDB中的EndDate
存储为string
,因此我将EndDate
声明为string
。但我需要在Time
中将此日期作为转到clientConfigData
。
答案 0 :(得分:2)
如果要在从/向MongoDB封送/解组值时更改值或进行类型转换,可以通过实现自定义封送/解组逻辑来实现。
您可以通过实施bson.Getter
和bson.Setter
接口来实现此目的。在这些方法中,您可以使用编组/解组的值执行任何操作。
最简单的方法是使用附加字段扩展您的clientConfigData
类型,该字段属于time.Time
类型,您需要的值:
type clientConfigData struct {
SMTPAssoc int `bson:"smtp_assoc"`
PlanType string `bson:"plan_type"`
EndDateStr string `bson:"end_date"`
EndDate time.Time `bson:"-"`
}
标记值为bson:"-"
,因为我们不希望它出现在MongoDB中。
现在是自定义封送/取消逻辑:
const endDateLayout = "2006-01-02 15:04:05" // Use your layout here
func (c *clientConfigData) SetBSON(raw bson.Raw) (err error) {
type my clientConfigData
if err = raw.Unmarshal((*my)(c)); err != nil {
return
}
c.EndDate, err = time.Parse(endDateLayout, c.EndDateStr)
return
}
func (c *clientConfigData) GetBSON() (interface{}, error) {
c.EndDateStr = c.EndDate.Format(endDateLayout)
type my *clientConfigData
return my(c), nil
}
这里发生的事情是SetBSON()
负责"填充"你的struct值的原始值来自MongoDB,GetBSON()
负责提供你想要保存的值(封送)。
加载时:SetBSON()
首先按原样解组值,然后从EndDate
日期值正确设置time.Time
字段(类型为string
)来自DB(EndDateStr
)。
保存时:GetBSON()
首先从EndDateStr
字段填写EndDate
字段(已保存的字段),然后返回,表示可以保存。< / p>
有一点需要注意:SetBSON()
和GetBSON()
都会在其中创建一个新的my
类型。这样做的原因是为了避免堆栈溢出。简单地返回clientConfigData
类型的值很糟糕,因为我们实施了bson.Getter
和bson.Setter
,因此SetBSON()
和GetBSON()
会被无休止地调用。新的my
类型没有这些方法,所以无限的#34;递归&#34;不会发生(type
关键字会创建一个新类型,并且它不会继承&#34;底层类型的方法。)
另见相关/类似问题:Set default date when inserting document with time.Time field