从Go访问MongoDB [英] Accesing MongoDB from Go
问题描述
我使用Go访问MongoDB,如下所示:
var configRes * clientConfigData
err:= clientDB。
C(clientConfigCollection)。
查找(bson.M {})。
一个(& configRes)
如果err!= nil {
return nil,errors.Wrap(err,find config collection)
}
其中
类型clientConfigData struct $ {
SMTPAssoc int`bson:smtp_assoc`
PlanType字符串`bson:plan_type`
EndDate字符串`bson:end_date`
}
现在,由于 EndDate
在MongoDB中被存储为 string
,所以我把 EndDate
声明为 string
。但是我需要在 clientConfigData
中访问这个日期为Go Time
。请帮助。
如果您希望更改值或进行类型转换时编组/ ,你可以通过实现一个自定义编组/解组逻辑来实现。
你可以通过执行 bson.Getter
和 bson.Setter
接口。在这些方法中,你可以做任何你想要的值,然后编组/取消编组值。
最简单的方法是扩展你的 clientConfigData
键入一个额外的字段,其中一个类型为 时间。时间
,您需要的值:
类型clientConfigData结构{
SMTPAssoc int`bson:smtp_assoc`
PlanType字符串`bson:plan_type`
EndDateStr字符串`bson:end_date`
EndDate time.Time`bson: - `
}
标记值 bson: -
,因为我们不希望它出现在MongoDB中。
现在是自定义封送/解封逻辑:
const endDateLayout =2006-01-02 15:04:05//在这里使用你的布局
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)
类型my * clientConfigData
return my (c),nil
}
这里发生的是 SetBSON()
负责用来自MongoDB的原始值填充你的结构值, GetBSON()
负责提供一个值你想保存(编组)。
加载时: SetBSON()
首先取消编组值,然后从中正确设置
来自数据库的日期值( EndDate
字段(类型 time.Time
)。字符串 EndDateStr
)。
保存时: GetBSON()
首先从<$ c中填充 EndDateStr
字段(保存的字段) $ c> EndDate 字段,然后直接返回,表示可以保存。
有一点需要注意: SetBSON()
和 GetBSON()
在里面创建一个新的 my
类型。这是为了避免堆栈溢出。简单地返回类型 clientConfigData
的值是不好的,因为我们实现了 bson.Getter
和 bson .Setter
,所以 SetBSON()
和 GetBSON()
会无休止地被调用。新的 my
类型没有这些方法,所以没有发生无穷无尽的递归( type
关键字创建一个新类型,它不会继承底层类型的方法)。
另请参阅相关/相似的问题:插入带time.Time字段的文档时设置默认日期
I am accessing MongoDB using Go as follows:
var configRes *clientConfigData
err := clientDB.
C(clientConfigCollection).
Find(bson.M{}).
One(&configRes)
if err != nil {
return nil, errors.Wrap(err, "finding config collection")
}
Where
type clientConfigData struct {
SMTPAssoc int `bson:"smtp_assoc"`
PlanType string `bson:"plan_type"`
EndDate string `bson:"end_date"`
}
Now since EndDate
in MongoDB is stored as string
so I declared EndDate
as string
. But I need to access this date as Go Time
in clientConfigData
. Please help.
If you want to change a value or do a type conversion when marshaling / unmarshaling your values from / to MongoDB, you may do it by implementing a custom marshaling / unmarshaling logic.
You can do this by implementing the bson.Getter
and bson.Setter
interfaces. Inside these methods, you may do whatever you want to with the values being marshaled / unmarshaled.
Easiest is to extend your clientConfigData
type with an additional field, one that will be of type time.Time
, the value you need:
type clientConfigData struct {
SMTPAssoc int `bson:"smtp_assoc"`
PlanType string `bson:"plan_type"`
EndDateStr string `bson:"end_date"`
EndDate time.Time `bson:"-"`
}
It has tag value bson:"-"
, because we don't want this to appear in MongoDB.
And now the custom marshaling / unmarhsaling logic:
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
}
What happens here is that SetBSON()
is responsible to "populate" your struct value with the raw value coming from MongoDB, and GetBSON()
is responsible to provide a value you want to be saved (marshaled).
When loading: SetBSON()
first unmarshals the value as-is, then properly sets the EndDate
field (which is of type time.Time
) from the string
date value that came from the DB (EndDateStr
).
When saving: GetBSON()
first fills the EndDateStr
field (the one that is saved) from the EndDate
field, and then simply returns, signaling that it is ok to save.
One thing to note: both SetBSON()
and GetBSON()
create a new my
type inside them. The reason for this is to avoid stack overflow. Simply returning a value of type clientConfigData
is bad, because we implemented bson.Getter
and bson.Setter
, so SetBSON()
and GetBSON()
would get called endlessly. The new my
type does not have these methods, so endless "recursion" does not happen (the type
keyword creates a new type, and it does not "inherit" methods of the underlying type).
Also see related / similar question: Set default date when inserting document with time.Time field
这篇关于从Go访问MongoDB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!