英文:
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论