使用mgo处理非结构化内部文档

huangapple go评论128阅读模式
英文:

unstructred inner document with mgo

问题

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

  1. { " _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 } }

最重要的是,在键 "value" 下的子文档结构是可变的,所以我无法为其创建一个结构。我尝试遵循这里的建议-https://stackoverflow.com/questions/18340031/unstructured-mongodb-collections-with-mgo

然后我写了这段代码---

  1. package main
  2. import ("fmt"
  3. "labix.org/v2/mgo" //导入mgo
  4. "labix.org/v2/mgo/bson"
  5. _ "reflect"
  6. )
  7. type AnalysisStruct struct{
  8. Id string `bson:"_id,omitempty"`
  9. Value bson.M `bson:",inline"`
  10. }
  11. func main() {
  12. var m AnalysisStruct
  13. //连接到本地mongodb
  14. session, err := mgo.Dial("localhost")
  15. if err != nil {
  16. panic(err)
  17. }
  18. defer session.Close()
  19. c := session.DB("my_analysis_db").C("analysis_mid_2")
  20. iter := c.Find(nil).Iter()
  21. for{
  22. if iter.Next(&m){
  23. fmt.Println(m.Value["value"]["total_visit"])
  24. }else{
  25. break
  26. }
  27. }
  28. }

当我尝试使用go build -v -o analyzer构建它时,它显示以下错误---

  1. ./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

  1. package main
  2. import ("fmt"
  3. "labix.org/v2/mgo" //导入mgo
  4. "labix.org/v2/mgo/bson"
  5. _ "reflect"
  6. )
  7. type AnalysisStruct struct{
  8. Id string `bson:"_id,omitempty"`
  9. Value bson.M `bson:",inline"`
  10. }
  11. func main() {
  12. var m AnalysisStruct
  13. //连接到本地mongodb
  14. session, err := mgo.Dial("localhost")
  15. if err != nil {
  16. panic(err)
  17. }
  18. defer session.Close()
  19. c := session.DB("consumergenepool_db").C("analysis_mid_2")
  20. iter := c.Find(nil).Iter()
  21. for{
  22. if iter.Next(&m){
  23. s := m.Value["value"].(bson.M)
  24. data, _ := bson.Marshal(s)
  25. var m bson.M
  26. _ = bson.Unmarshal(data, &m)
  27. fmt.Println(m)
  28. for k, v := range m{
  29. fmt.Print(k)
  30. fmt.Print(" :: ")
  31. fmt.Println(v)
  32. }
  33. }else{
  34. break
  35. }
  36. }
  37. }

请告诉我您对此的想法。

谢谢

英文:

I have a document which has this following structure

  1. { "_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 } }

THE MOST IMPORTANT thing is that the sub document structure under the key "value" is variable so I can not create a structure for that. I tried to follow the suggestion here - https://stackoverflow.com/questions/18340031/unstructured-mongodb-collections-with-mgo

And I came with this code ---

  1. package main
  2. import ("fmt"
  3. "labix.org/v2/mgo" //importing mgo
  4. "labix.org/v2/mgo/bson"
  5. _ "reflect"
  6. )
  7. type AnalysisStruct struct{
  8. Id string `bson:"_id,omitempty"`
  9. Value bson.M `bson:",inline"`
  10. }
  11. func main() {
  12. var m AnalysisStruct
  13. //connecting to localhost mongodb
  14. session, err := mgo.Dial("localhost")
  15. if err != nil {
  16. panic(err)
  17. }
  18. defer session.Close()
  19. c := session.DB("my_analysis_db").C("analysis_mid_2")
  20. iter := c.Find(nil).Iter()
  21. for{
  22. if iter.Next(&m){
  23. fmt.Println(m.Value["value"]["total_visit"])
  24. }else{
  25. break
  26. }
  27. }
  28. }

When I try to build this using go build -v -o analyzer it shows me this error---

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

I am terribly stuck with this. Can not get anything going. Please can somebody help?

Thanks


I cam up with this code after doing some research. Not the most optimized one for sure. But for my case it works. Took help from
http://blog.denevell.org/golang-interface-type-assertions-switch.html

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

  1. package main
  2. import ("fmt"
  3. "labix.org/v2/mgo" //importing mgo
  4. "labix.org/v2/mgo/bson"
  5. _ "reflect"
  6. )
  7. type AnalysisStruct struct{
  8. Id string `bson:"_id,omitempty"`
  9. Value bson.M `bson:",inline"`
  10. }
  11. func main() {
  12. var m AnalysisStruct
  13. //connecting to localhost mongodb
  14. session, err := mgo.Dial("localhost")
  15. if err != nil {
  16. panic(err)
  17. }
  18. defer session.Close()
  19. c := session.DB("consumergenepool_db").C("analysis_mid_2")
  20. iter := c.Find(nil).Iter()
  21. for{
  22. if iter.Next(&m){
  23. s := m.Value["value"].(bson.M)
  24. data, _ := bson.Marshal(s)
  25. var m bson.M
  26. _ = bson.Unmarshal(data, &m)
  27. fmt.Println(m)
  28. for k, v := range m{
  29. fmt.Print(k)
  30. fmt.Print(" :: ")
  31. fmt.Println(v)
  32. }
  33. }else{
  34. break
  35. }
  36. }
  37. }

Let me know your thoughts on this.

Thanks

答案1

得分: 1

当测试新东西时,总是要使用大量的fmt.Printf来感受它,话虽如此。

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

应该改为

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

而且

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

应该改为:

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

你的m.Value是"value",所以你可以直接使用m.Value["total_visit"]

inline只能用来捕获原始结构中不存在的字段,但由于你的结构只有两个字段(Id和Value),所以不需要它。

现在,如果你要保留,inline,你可以这样使用:

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

因为m.Value["value"]是一个interface{},你必须将其重新断言为其原始值bson.M,然后才能使用它。

英文:

When testing something new always use a lot of fmt.Printf's to get a feel for it, that being said.

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

Should be

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

And

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

Should be:

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

Your m.Value is "value", so you can use m.Value["total_visit"] directly.

<kbd>playground</kbd>

//edit

You can only use inline to catch any fields that that aren't a part of the original struct, but since your struct only has 2 fields (Id and Value), you don't need it.

Now if you were to keep ,inline you would use it like this:

  1. if v, ok := m.Value[&quot;value&quot;].(bson.M); ok {
  2. fmt.Println(v[&quot;total_visit&quot;])
  3. }

Because m.Value[&quot;value&quot;] is an interface{}, you have to type assert it back to it's original value, bson.M before you could use it.

huangapple
  • 本文由 发表于 2014年7月8日 21:13:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/24632836.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定