How to insert array of objects into MongoDB using Go

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

How to insert array of objects into MongoDB using Go

问题

我有一个来自API的JSON数据,我想使用mgo包将其保存到MongoDB中。我的JSON数据如下所示:

{
"something": "value",
"collection": [
{ "obj1": "value" }
// ...(这里有可变数量的对象)
]
}

为了保存这些数据,我在我的Go应用程序中创建了一个新的type,如下所示:

type MyData struct {
Something string
Collection []string // 实际上包含的不仅仅是字符串,但如果我只能保存字符串,我会很满意
}

mongoSess, err := mgo.Dial("localhost:27017")
if err != nil {
panic(err)
}
defer mongoSess.Close()

c := mongoSess.DB("mydatabase").C("mycollection")
insertErr := c.Insert(&MyData{something, collection})

这段代码是可以工作的,但问题是它没有保存任何数据到我的集合字段中,这个字段应该是一个JSON对象的数组。完全没有保存任何数据。这是Mongo的输出:

{ "_id" : ObjectId("5520c535a236d8a9a215d096"), "something" : "value", "collection" : [ ] }

有人能发现我做错了什么吗?显然我对Go还不熟悉,对类型有困惑。

解决方案

这里的答案对我帮助很大。我有责任没有正确解释事情,因为答案让我找对了方向,但没有直接解决问题。这是实际的解决方案。

package main

import (
"encoding/json"
"github.com/bitly/go-simplejson"
"gopkg.in/mgo.v2"
// "gopkg.in/mgo.v2/bson"
// 还使用了其他包
)

type MyData struct {
Something int
Collection []interface{}
}

func main() {
// 我使用SimpleJson来解析JSON
collection, cerr := jsonFromExternalApi.Get("collection").Array()
if cerr != nil {
logger.Debug.Fatalln(cerr)
}

// 将响应保存到Mongo(省略了所有连接代码)
c := mongoSess.DB("mydb").C("mycollection")
insertErr := c.Insert(&Producer{npn, licenses })

}

问题在于SimpleJSON将来自API调用的对象数组返回为[]interface{}。我不知道我可以简单地将结构的一部分声明为接口,所以我没有纠正Go编译器告诉我错误的地方,而是让事情变得比应该更困难。

对于习惯了弱类型脚本语言的人来说,这样的东西确实让我困惑,有时很难看到好处,但希望这对某个人有所帮助。

英文:

I have JSON from an API that I want to save to MongoDB using the mgo package. My JSON looks like this:

{
  "something": "value"
  "collection": [
    { "obj1": "value" }
    // ... (Variable number of objects here)
  ]
}

To save this data I've created a new type in my Go application that looks like this:

type MyData struct {
  Something string
  Collection []string // This actually contains more than strings but I'll be happy if I can just get strings saved
}

mongoSess, err := mgo.Dial("localhost:27017")
if err != nil {
  panic(err)
}
defer mongoSess.Close()

c := mongoSess.DB("mydatabase").C("mycollection")
insertErr := c.Insert(&MyData{something, collection})

This code works but the problem is that it isn't saving anything in my collection field which should be an array of JSON objects. Nothing at all. I get the keys in my database and they are the right type but they have no data. Here's what the Mongo output is:

{ "_id" : ObjectId("5520c535a236d8a9a215d096"), "something" : "value", "collection" : [ ] }

Can anyone spot what it is I'm doing wrong? I'm obviously new to Go and having trouble with types.

Solution

The answers here really helped me a lot. I'm at fault for not properly explaining things as the answers sent me on the right track but didn't solve the issue directly. Here's what the actual solution is.

package main

import (
  "encoding/json"
  "github.com/bitly/go-simplejson"
  "gopkg.in/mgo.v2"
  //"gopkg.in/mgo.v2/bson"
  // Other packages are used as well
)

type MyData struct {
  Something int
  Collection []interface{}
}

func main() {
    // I'm using SimpleJson for parsing JSON
    collection, cerr := jsonFromExternalApi.Get("collection").Array()
    if cerr != nil {
      logger.Debug.Fatalln(cerr)
    }

    // Save response to Mongo (leaving out all the connection code)
    c := mongoSess.DB("mydb").C("mycollection")
    insertErr := c.Insert(&Producer{npn, licenses })
}

The issue was that SimpleJSON was returning the array of objects from my API call as a []interface{}. I was not aware I could simply declare part of a struct to be an interface so instead of just correcting what Go's compiler was telling me was wrong I was making it way harder than it should have been.

Coming from loosely typed scripting languages, stuff like this really trips me up and sometimes its hard to see the benefit but hopefully this helps someone out one day.

答案1

得分: 4

看起来你的数据结构有问题。

insertErr := c.Insert(&MyData{something, collection})

其中,something应该是一个string,collection应该是一个slice

你的代码应该像这样:

insertErr := c.Insert(&MyData{"something", []string{"obj1", "value"}})

这里是可工作的代码示例。

[{Something:something Collection:[obj1 value]} {Something:something Collection:[obj1 value]} {Something:something Collection:[obj1 value]} {Something:something Collection:[obj1 value]}]

如果需要进一步参考,mgo有很好的文档,你可以在这里找到有关运行MongoDB查询的示例代码和详细信息。

英文:

Looks you have the wrong data structure.

insertErr := c.Insert(&MyData{something, collection})

something => string and collection => slice

You code should be like this:

insertErr := c.Insert(&MyData{"something", []string{"obj1", "value"}})

Here is the working code.

[{Something:something Collection:[obj1 value]} {Something:something Collection:[obj1 value]} {Something:something Collection:[obj1 value]} {Something:something Collection:[obj1 value]}]

For further reference, mgo has great documentation and you can find sample code and details about running mongodb queries here.

答案2

得分: 1

在你的MyData结构体中,你没有为Collection定义正确的类型。

Collection []string    //这是你定义的内容。

但是从Json中,你得到的不是string数组,而是map[string]interface{}

这就是你没有正确填充MyData结构体的原因

正确的MyData结构体应该是

type MyData struct {
 Something string   
 Collection map[string]string // 这实际上包含的不仅仅是字符串,但如果我只能保存字符串,我会很高兴
}
英文:

Here you are not defining proper type to Collection in your MyData struct.

Collection []string    //This is what you are defining.

But from Json you are not getting string array,you are getting map[string]interface{}

> This is the reason you are not filling Mydata struct properly

Correct MyData struct will be

type MyData struct {
 Something string   
 Collection map[string]string // This actually contains more than strings but I'll be happy if I can just get strings saved 
}

huangapple
  • 本文由 发表于 2015年4月5日 13:27:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/29454410.html
匿名

发表评论

匿名网友

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

确定