mgo如何直接存储json?

mongoDB里面按理说是可以直接存储json的。

现在我有一个现成的json,如何存入mongoDB呢?

貌似mgo里给的例子都是转化成struct再存,岂不是多此一举?

共 10 个回复


16779242

另外,假如temp为一个json转化而来的字符串。

当我把temp作为一个key对应的value存储的时候,它是以字符串形式存储的。

如何才能将其作为一个json存储在里面?

也就是这个key对应的属性就是一个大json。

# 0

16779242

...国庆放假回来还是没解答啊。。看样子这个问题难度不小

# 1

jimmykuu

MongoDB里面其实是bson。

mgo不支持你要的把json直接存成bson。

# 2

16779242

尝试了一个取巧的办法,居然成功了。。。。

假设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

qingo

要的就是这个,谢谢~

# 4

edl7878

改正一个错误

如前所述:

假设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

这里unmarshal可以保证二进制流是bson兼容的,得到的数据再往库里存就不会出错了。

感觉客户端把对象变为bson,go把bson变成interface,然后数据库再把interface变成bson,就好晕啊。

# 6

zxfonline

golang struct to json,save as mongodb document
and 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:30
insert 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

在改正五楼的一个错误,如果对于是json类型的数据,

bson.Unmarshal(b, &f)

需要改为

bson.UnmarshalJSON(b, &f)

后面的全部ok

# 8

Tristone

是个好问题 然而回答一堆错误

# 9