从Go访问MongoDB [英] Accesing MongoDB from Go

查看:129
本文介绍了从Go访问MongoDB的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆