1

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.

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

1 Comment

This is the best answer but not exactly correct for my case. But that's my fault for not being detailed enough. I was absolutely defining my type incorrectly. I was using the SimpleJson library and my array of objects was coming back as []interface{}. By changing my Collection to []interface{} I was able to get the entire array of objects saved into Mongo in the exact same format it was given.
1

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 
}

1 Comment

Thank you, I really want to select this as the right answer but I can only choose one. I changed my JSON retrieving code to get a straight []interface{} and made a simple change to my Collection type based on your response. Thank you so much. It wasn't the actual solution to my problem but it led me in the right direction and I was able to get it within no time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.