Search code examples
jsonmongodbgoslicemgo

Insert a slice result JSON into MongoDB


I'm using the mgo driver for MongoDB, with the Gin framework.

type  Users struct {
    User_id *string  `json:"id user" bson:"id user"`
    Images  []string `json:"images" bson:"images"`
}

I have this function which tries to convert the slice into JSON.

The slice here is UsersTotal

func GetUsersApi(c *gin.Context) {

    UsersTotal, err := GetUsers()

    if err != nil {
        fmt.Println("error:", err)
    }

    c.JSON(http.StatusOK, gin.H{
        "Count Users": len(UsersTotal),
        "Users Found ": UsersTotal,
    })


    session, err := mgo.Dial(URL)
    if err == nil {
        fmt.Println("Connection to mongodb established ok!!")
        cc := session.DB("UsersDB").C("results")

        err22 := cc.Insert(&UsersTotal)
        if err22 != nil {
            fmt.Println("error insertion ", err22)
        }
    }
    session.Close()
   }

Running it I get the following error:

error insertion Wrong type for documents[0]. Expected a object, got a array.


Solution

  • Inserting multiple documents is the same as inserting a single one because the Collection.Insert() method has a variadic parameter:

    func (c *Collection) Insert(docs ...interface{}) error
    

    One thing you should note is that it expects interface{} values. Value of any type qualifies "to be" an interface{}. Another thing you should note is that only the slice type []interface{} qualifies to be []interface{}, a user slice []User does not. For details, see Type converting slices of interfaces in go

    So simply create a copy of your users slice where the copy has a type of []interface{}, and that you can directly pass to Collection.Insert():

    docs := make([]interface{}, len(UsersTotal))
    for i, u := range UsersTotal {
        docs[i] = u
    }
    
    err := cc.Insert(docs...)
    // Handle error
    

    Also please do not connect to MongodB in your handler. Do it once, on app startup, store the global connection / session, and clone / copy it when needed. For details see mgo - query performance seems consistently slow (500-650ms); and too many open files in mgo go server.