英文:
unstructred inner document with mgo
问题
我有一个具有以下结构的文档:
{ " _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
然后我写了这段代码---
package main
import ("fmt"
"labix.org/v2/mgo" //导入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
//连接到本地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构建它时,它显示以下错误---
./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" //导入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
//连接到本地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
}
}
}
请告诉我您对此的想法。
谢谢
英文:
I have a document which has this following structure
{ "_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 ---
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
}
}
}
When I try to build this using go build -v -o analyzer it shows me this error---
./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
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
}
}
}
Let me know your thoughts on this.
Thanks
答案1
得分: 1
当测试新东西时,总是要使用大量的fmt.Printf
来感受它,话虽如此。
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
是"value",所以你可以直接使用m.Value["total_visit"]
。
inline
只能用来捕获原始结构中不存在的字段,但由于你的结构只有两个字段(Id和Value)
,所以不需要它。
现在,如果你要保留,inline
,你可以这样使用:
if v, ok := m.Value["value"].(bson.M); ok {
fmt.Println(v["total_visit"])
}
因为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.
Value bson.M `bson:",inline"`
Should be
Value bson.M `bson:"value,omitempty"`
And
fmt.Println(m.Value["value"]["total_visit"])
Should be:
fmt.Printf("%#v\n", m)
fmt.Println(m.Value["total_visit"])
Your m.Value
is "value", so you can use m.Value["total_visit"]
directly.
//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:
if v, ok := m.Value["value"].(bson.M); ok {
fmt.Println(v["total_visit"])
}
Because m.Value["value"]
is an interface{}
, you have to type assert it back to it's original value, bson.M
before you could use it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论