mgo如何直接存储json? 16779242 发布 2014-09-28 17:45 浏览 9509 回复 10 问与答 mongoDB里面按理说是可以直接存储json的。 现在我有一个现成的json,如何存入mongoDB呢? 貌似mgo里给的例子都是转化成struct再存,岂不是多此一举?
16779242 2014-09-28 18:03 另外,假如temp为一个json转化而来的字符串。 当我把temp作为一个key对应的value存储的时候,它是以字符串形式存储的。 如何才能将其作为一个json存储在里面? 也就是这个key对应的属性就是一个大json。 # 0
16779242 2014-10-08 14:27 尝试了一个取巧的办法,居然成功了。。。。 假设b为所取到的json的二进制数据流,可以这么做: 首先 import( "encoding/json" "gopkg.in/mgo.v2" ) 然后具体代码如下(MongoDBUrl,Username,Password分别为mongoDB的连接配置): var f interface{} err := json.Unmarshal(b, &f) if err != nil { //TODO:错误处理 return } session,err := mgo.DialWithInfo(&mgo.DialInfo{Addrs: []string{MongoDBUrl}, Username: Username, Password: Password}) if err != nil { //TODO:错误处理 return } defer session.Close() c := session.DB(MongoDBName).C(collection) err = c.Insert(f) if err != nil { //TODO:错误处理 } 共享上来,后面遇见同样坑的同学,我已帮你填平了…… # 3
edl7878 2016-04-04 23:50 改正一个错误如前所述:假设b为所取到的json的二进制数据流,那么就是bson了。上面的代码,最关键的一句: json.Unmarshal(b, &f)需要修改为: bson.Unmarshal(b, &f)就是把bson二进制码给映射到一个接口中。 这一句OK了,后面的全部OK。 func requestJsonAndAssetServerUrlHandle(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { fmt.Println("requestJsonAndAssetServerUrlHandle==>") //func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error) file, header, err := r.FormFile("webServiceId") defer file.Close() fmt.Println("HeadFilename:", header.Filename) fmt.Println("file:", file) if err != nil { fmt.Fprintln(w, err) return } var f interface{} data, err := ioutil.ReadAll(file) bson.Unmarshal(data, &f) fmt.Println("Unmarshaled data:", f) session, err := mgo.Dial("127.0.0.1:27017") if err != nil { fmt.Println("DB connect err:", err.Error()) panic(err) } defer session.Close() // Optional. Switch the session to a monotonic behavior. session.SetMode(mgo.Monotonic, true) c := session.DB("test").C("people") err = c.Insert(f) if err != nil { fmt.Println("Insert err:", err.Error()) log.Fatal(err) } } 几个注意的地方:1、二进制发过来,对应multipart.file,go是把它当做文件来处理2、文件要读成byte[],才可以unmarshal,这里就是读文件分多大的缓冲区,怎样一次读完,可以参考第16行代码,该代码是参考这里的大神的3、如改正的那个错误,因为发过来的是bson格式,所以,要用bson来unmarshal,而不是json,marshal整理完毕,就可以往数据库存了。 # 5
edl7878 2016-04-04 23:56 这里unmarshal可以保证二进制流是bson兼容的,得到的数据再往库里存就不会出错了。 感觉客户端把对象变为bson,go把bson变成interface,然后数据库再把interface变成bson,就好晕啊。 # 6
zxfonline 2016-04-16 16:24 golang struct to json,save as mongodb documentand mongodb document parse to struct func test package main import ( "fmt" "time" "github.com/zxfonline/json" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" ) type NodeA struct { Node1 int Node2 string } type NodeB struct { NodeAcode int NodeBcode string NodeASon map[float64]*NodeA NodeBSon []*NodeA NodeCcode time.Time } type NodeB1 struct { NodeAcode int NodeBcode1 string NodeASon map[float64]*NodeA NodeBSon []*NodeA } func main() { node := &NodeB{NodeAcode: 21, NodeBcode: "21", NodeCcode: time.Now()} fmt.Println(node.NodeCcode.Format("2006-01-02 15:04:05")) sonst := make(map[float64]*NodeA) sonst[1.1] = &NodeA{Node1: 111, Node2: "111"} sonst[2.2] = &NodeA{Node1: 112, Node2: "112"} node.NodeASon = sonst sona := make([]*NodeA, 0) sona = append(sona, &NodeA{Node1: 211, Node2: "211"}) sona = append(sona, &NodeA{Node1: 212, Node2: "212"}) node.NodeBSon = sona b, err := json.Marshal(&node) if err != nil { panic(err) } fmt.Println("insert struct json=", string(b)) var f interface{} err = json.Unmarshal([]byte(b), &f) if err != nil { panic(err) } var session *mgo.Session session, err = mgo.Dial("localhost:27017") if err != nil { panic(err) } defer session.Close() coll := session.DB("test").C("test") err = coll.Insert(f) if err != nil { panic(err) } var q []bson.M coll.Find(nil).All(&q) for _, info := range q { b, err = json.Marshal(info) if err != nil { panic(err) } fmt.Println("parse struct json=", string(b)) nodeN := &NodeB{} err = json.Unmarshal([]byte(b), nodeN) if err != nil { panic(err) } //test content same? b, err = json.Marshal(&node) if err != nil { panic(err) } fmt.Println("new struct json=", string(b)) fmt.Println(nodeN.NodeCcode.Format("2006-01-02 15:04:05")) } } 2016-04-16 16:10:30insert struct json= {“NodeAcode”:21,”NodeBcode”:”21”,”NodeASon”:{“1.1”:{“Node1”:111,”Node2”:”111”},”2.2”:{“Node1”:112,”Node2”:”112”}},”NodeBSon”:[{“Node1”:211,”Node2”:”211”},{“Node1”:212,”Node2”:”212”}],”NodeCcode”:”2016-04-16T16:10:30.9692215+08:00”} new struct json= {“NodeAcode”:21,”NodeBcode”:”21”,”NodeASon”:{“1.1”:{“Node1”:111,”Node2”:”111”},”2.2”:{“Node1”:112,”Node2”:”112”}},”NodeBSon”:[{“Node1”:211,”Node2”:”211”},{“Node1”:212,”Node2”:”212”}],”NodeCcode”:”2016-04-16T16:10:30.9692215+08:00”}2016-04-16 16:10:30 # 7
lyyyy 2020-07-06 15:35 在改正五楼的一个错误,如果对于是json类型的数据, bson.Unmarshal(b, &f) 需要改为 bson.UnmarshalJSON(b, &f) 后面的全部ok # 8
共 10 个回复
16779242
另外,假如temp为一个json转化而来的字符串。
当我把temp作为一个key对应的value存储的时候,它是以字符串形式存储的。
如何才能将其作为一个json存储在里面?
也就是这个key对应的属性就是一个大json。
16779242
...国庆放假回来还是没解答啊。。看样子这个问题难度不小
jimmykuu
MongoDB里面其实是bson。
mgo不支持你要的把json直接存成bson。
16779242
尝试了一个取巧的办法,居然成功了。。。。
假设b为所取到的json的二进制数据流,可以这么做: 首先
然后具体代码如下(MongoDBUrl,Username,Password分别为mongoDB的连接配置):
共享上来,后面遇见同样坑的同学,我已帮你填平了……
qingo
要的就是这个,谢谢~
edl7878
改正一个错误
如前所述:
假设b为所取到的json的二进制数据流,那么就是bson了。上面的代码,最关键的一句:
json.Unmarshal(b, &f)
需要修改为:
bson.Unmarshal(b, &f)
就是把bson二进制码给映射到一个接口中。
这一句OK了,后面的全部OK。
几个注意的地方:
1、二进制发过来,对应multipart.file,go是把它当做文件来处理
2、文件要读成byte[],才可以unmarshal,这里就是读文件分多大的缓冲区,怎样一次读完,可以参考第16行代码,该代码是参考这里的大神的
3、如改正的那个错误,因为发过来的是bson格式,所以,要用bson来unmarshal,而不是json,marshal整理完毕,就可以往数据库存了。
edl7878
这里unmarshal可以保证二进制流是bson兼容的,得到的数据再往库里存就不会出错了。
感觉客户端把对象变为bson,go把bson变成interface,然后数据库再把interface变成bson,就好晕啊。
zxfonline
golang struct to json,save as mongodb document
and mongodb document parse to struct func test
lyyyy
在改正五楼的一个错误,如果对于是json类型的数据,
bson.Unmarshal(b, &f)
需要改为
bson.UnmarshalJSON(b, &f)
后面的全部ok
Tristone
是个好问题 然而回答一堆错误