1

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.

icza
  • 389,944
  • 63
  • 907
  • 827
Medo
  • 83
  • 1
  • 8
  • does `GetUsers` return `[]Users, error`? – Hadi May 08 '18 at 09:57
  • yes @Hadi , it returns an `array of Users` with an `error` to check , my problem is when inserting this `slice: UsersTotal` into my `mongoDB` – Medo May 08 '18 at 10:00
  • Hmm, please iterate over your array and then insert each of them. I think it'll work. – Hadi May 08 '18 at 10:02
  • @Hadi you mean like doing a range on the slice and try to iterate on each row, it sounds to will effect on the runtime , i am handling with a huge result here – Medo May 08 '18 at 10:04
  • did that work for you @Data_Geek ? – Hadi May 08 '18 at 10:06
  • @icza could you please give a help here ?? – Medo May 08 '18 at 10:07
  • `MongoDB` is a document-oriented database which simply means you have to provide a document. What you are trying to do here is to insert an array of documents(https://docs.mongodb.com/manual/reference/method/db.collection.insertMany/). Maybe `mgo` has an api for dealing with this situation. – Hadi May 08 '18 at 10:10
  • @Hadi yes i tried it , it works but here i meant to find a better why in using the package not a hard coded looping – Medo May 08 '18 at 10:14
  • Additionally `mgo` is unmaintained https://github.com/go-mgo/mgo#this-is-unmaintained – Andrei Simionescu May 08 '18 at 10:15
  • 1
    try this `cc.Insert(UsersTotal...)` @Data_Geek – Hadi May 08 '18 at 10:19
  • @AndreiSimionescu , clearly i am trying to move on into golabsign as an updated mgo [globalsign](https://github.com/globalsign/mgo) – Medo May 08 '18 at 10:20
  • @Hadi aleardy done i got this error : ` cannot use UsersTotal (type []Users) as type []interface {} in argument to cc.Insert` – Medo May 08 '18 at 10:22
  • @Data_Geek see https://golang.org/doc/faq#convert_slice_of_interface – Hadi May 08 '18 at 10:37

1 Answers1

2

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.

icza
  • 389,944
  • 63
  • 907
  • 827
  • @Data_Geek If there is no error, then either you pass 0 documents to insert, or you look for the inserted documents in the wrong place (e.g. another db, another collection etc.). If everything seems to match, please edit the question and post the code you tried (including the error handling). – icza May 08 '18 at 11:07
  • ,It was an error database switch , perfectly working thanks for the help :-) – Medo May 08 '18 at 11:18