3

我有一个具有以下结构的文档

{ "_id" : "736722976", "value" : { "total_visit" : 4, "FIFA World Cup 2014" : 1, "Germany" : 1, "Algeria" : 1, "Thomas Muller" : 1, "Mesut Ozil" : 1, "Monsoon" : 1, "India Meteorological Department (IMD)" : 1, "Web Exclusive" : 2, "Specials" : 1, "Tapas Pal" : 1, "Twitter Trends" : 1, "Sunanda Pushkar" : 1, "Shashi Tharoor" : 1, "AIIMS" : 1, "special" : 1 } }

最重要的是,键“值”下的子文档结构是可变的,所以我无法为此创建结构。我试着按照这里的建议 -使用 mgo 的非结构化 MongoDB 集合

我带着这段代码来了——

package main

import ("fmt"
"labix.org/v2/mgo"  //importing mgo
"labix.org/v2/mgo/bson"
_ "reflect"
)

type AnalysisStruct struct{
  Id string `bson:"_id,omitempty"`
  Value bson.M `bson:",inline"`
}

func main() {
    var m AnalysisStruct
    //connecting to localhost mongodb
    session, err := mgo.Dial("localhost")
    if err != nil {  
        panic(err)
    }
    defer session.Close()
    c := session.DB("my_analysis_db").C("analysis_mid_2")
    iter := c.Find(nil).Iter()
    for{
      if iter.Next(&m){
          fmt.Println(m.Value["value"]["total_visit"])
      }else{
          break
      }
    }

}

当我尝试使用 go build -v -o 分析器构建它时,它向我显示了这个错误---

./analyzer.go:32: invalid operation: m.Value["value"]["total_visit"] (index of type interface {})

我非常坚持这一点。什么也做不了。请问有人可以帮忙吗?

谢谢


在做了一些研究后,我想出了这段代码。肯定不是最优化的。但就我而言,它有效。从 http://blog.denevell.org/golang-interface-type-assertions-switch.html获得帮助

https://groups.google.com/forum/#!topic/mgo-users/JYE-CP15az4

package main

import ("fmt"
"labix.org/v2/mgo"  //importing mgo
"labix.org/v2/mgo/bson"
_ "reflect"
)

type AnalysisStruct struct{
  Id string `bson:"_id,omitempty"`
  Value bson.M `bson:",inline"`
}

func main() {
    var m AnalysisStruct
    //connecting to localhost mongodb
    session, err := mgo.Dial("localhost")
    if err != nil {  
        panic(err)
    }
    defer session.Close()
    c := session.DB("consumergenepool_db").C("analysis_mid_2")
    iter := c.Find(nil).Iter()
    for{
      if iter.Next(&m){
           s := m.Value["value"].(bson.M)
           data, _ := bson.Marshal(s)
           var m bson.M
           _ = bson.Unmarshal(data, &m)
           fmt.Println(m)
           for k, v := range m{
              fmt.Print(k)
              fmt.Print(" :: ")
              fmt.Println(v)
           }
      }else{
          break
      }
    }

}

让我知道你对此的看法。

谢谢

4

1 回答 1

1

话虽如此,在测试新事物时,总是使用大量的fmt.Printf's 来感受它。

Value bson.M `bson:",inline"`

应该

Value bson.M `bson:"value,omitempty"`

fmt.Println(m.Value["value"]["total_visit"])

应该:

fmt.Printf("%#v\n", m)
fmt.Println(m.Value["total_visit"])

m.Value的是“价值”,所以你可以m.Value["total_visit"]直接使用。

playground

//编辑

您只能用于inline捕获不属于原始结构的任何字段,但由于您的结构只有 2 个字段(Id and Value),因此您不需要它。

现在,如果你要保留,inline,你会像这样使用它:

    if v, ok := m.Value["value"].(bson.M); ok {
        fmt.Println(v["total_visit"])
    }

因为m.Value["value"]is an interface{},所以您必须先将其键入 assert它的原始值,bson.M然后才能使用它。

于 2014-07-08T13:31:12.220 回答