从Go访问MongoDB
我使用Go访问MongoDB,如下所示:从Go访问MongoDB,mongodb,go,mgo,Mongodb,Go,Mgo,我使用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 clientConfigDat
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
。但是我需要在clientConfigData
中以GoTime
的形式访问此日期。如果您想在将值从MongoDB封送/解封时更改值或进行类型转换,可以通过实现自定义封送/解封逻辑来实现
您可以通过实现和接口来实现这一点。在这些方法中,您可以对封送/取消封送的值执行任何操作
最简单的方法是使用附加字段扩展clientConfigData
类型,该字段的类型为您需要的值:
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()
负责使用来自MongoDB的原始值“填充”结构值,GetBSON()
负责提供要保存(封送)的值
加载时:SetBSON()
首先按原样解组值,然后从数据库(EndDateStr
)的字符串中正确设置EndDate
字段(类型为time.time
)
保存时:GetBSON()
首先从EndDate
字段填充EndDateStr
字段(保存的字段),然后返回,表示可以保存
需要注意的一点是:SetBSON()
和GetBSON()
在它们内部创建一个新的my
类型。这样做的原因是为了避免堆栈溢出。简单地返回类型为clientConfigData
的值是不好的,因为我们实现了bson.Getter
和bson.Setter
,所以SetBSON()
和GetBSON()
将被无休止地调用。新的my
类型没有这些方法,因此不会发生无休止的“递归”(关键字type
创建一个新类型,并且不会“继承”基础类型的方法)
另请参见相关/类似的问题:因此,如果我们没有实现bson.Getter
和bson.Setter
,我们可以简单地返回clienConfigData
,对吗?但在这种情况下,我们最好不要。这是正确的吗?你的问题没有真正意义,因为添加GetBSON()
和SetBSON()
实现了Getter
和Setter
(Getter
和Setter
是定义GetBSON()
和SetBSON()
的接口)。如果你不添加这些方法,就没有什么可以返回的了。非常感谢@icza@icza我只有一个问题,如何对从SetBSON
@SyedQasimRizvi返回的错误进行错误处理您没有处理它,因为您不是调用SetBSON()
的人。当从MongoDB加载值时,mgo
包检查值是否实现了Setter
,如果实现了,则调用其SetBSON()
进行解组。需要处理由它返回的错误的是mgo
包,它可能被包装、记录或由您调用的外部函数返回(例如Find().All()
或Find().One()
)。