登录
首页 >  Golang >  Go问答

遍历 MongoDB 集合并将其解析为不同的 Go 结构

来源:stackoverflow

时间:2024-02-23 23:09:24 141浏览 收藏

小伙伴们有没有觉得学习Golang很有意思?有意思就对了!今天就给大家带来《遍历 MongoDB 集合并将其解析为不同的 Go 结构》,以下内容将会涉及到,若是在学习中对其中部分知识点有疑问,或许看了本文就能帮到你!

问题内容

我在 mongodb 实例中有一系列集合,我想提取所有集合并解码集合中的所有文档,以便我可以随时更改它们。

我正在使用 go 列出集合名称:

...
collections, err := db.listcollectionnames(context.todo(), bson.m{})
if err != nil {
    log.fatalf("failed to get coll names: %v", err)
}

for _, coll := range collections {
    collection := db.collection(coll)
...

这可以完美地工作,下一步是打开每个集合的游标并循环游标并在每个对象上调用解码为其相应的类型。

我已经定义了类型包中的所有类型:

type announcements struct {
    id            string    `bson:"_id"`
    content       string    `bson:"content"`
    title         string    `bson:"title"`
    datemodified  time.time `bson:"datemodified,omitempty"`
    modifiedby    string    `bson:"modifiedby,omitempty"`
}

问题是我无法定义用于动态解码的变量。

需要为每个集合重复此代码

var obj announcements // this would need to be dynamic

for cursor.next(context.background()) {
    err := cursor.decode(&obj)
    if err != nil {
        log.fatal(err)
    }

    log.printf("%#v\n", obj)
}

有没有办法做到这一点而不需要重复多次?我意识到动态类型语言对此会更好。在将工作迁移到脚本语言之前想询问一下。

我尝试使用reflect包和switch语句动态实例化变量并使用interface{}类型,但这强制解码使用bson类型而不是我定义的结构。

--编辑--

我尝试使用映射将集合名称链接到类型,但无济于事。

var collections = map[string]interface{}{
    "announcements":          announcements{},
    "badges":                 badges{},
    "betauser":               betauser{},
    "bonuslearningitems":     bonuslearningitems{},
    "books":                  books{},
...
}

因此,当我使用 obj var 时,我尝试了如下分配:

var obj types.Collections[coll]

如果我循环到公告集合,希望能给我一个公告类型的变量。但是当我调用解码时它返回 bson 类型。

我需要动态定义 obj 变量类型。


正确答案


有很多方法可以做到这一点。其中之一是使用回调函数:

func process(cursor *mongo.cursor, cb func(), out interface{}) {
  for cursor.next(context.background()) {
     err := cursor.decode(out)
     if err != nil {
         log.fatal(err)
     }
     cb()
     log.printf("%#v\n", obj)
  }
}

然后定义一个地图:

type collhandler struct {
   new func() interface{}
   process func(interface{})
}


var collections=map[string]func() interface{} {
   "announcements":   collhandler{
     new: func() interface {} {return &announcement{}},
     process: func(data interface{}) {
        processannouncements(data.(*announcement))
     },
   },
   ...
}

然后你可以:

handler:=collections[collectionName]
obj:=handler.New()
process(cursor,func() {
   handler.Process(obj)
  },
  &obj)

这样,您就可以将迭代放入公共函数中,并使用闭包来处理特定于类型的逻辑。

今天关于《遍历 MongoDB 集合并将其解析为不同的 Go 结构》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>