6

I am trying to insert data that is stored in an array of struct into a MongoDB using the go.mongodb.org/mongo-driver library. My struct is

type Statement struct {
    ProductID        string `bson:"product_id" json:"product_id"`
    ModelNum         string `bson:"model_num" json:"model_num"`
    Title            string `bson:"title" json:"title"`
}

and my insertion code is

func insert(stmts []Statement) {
    client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://127.0.0.1:27017"))
    if err != nil {
        log.Fatal(err)
    }
    ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
    err = client.Connect(ctx)
    if err != nil {
        log.Fatal(err)
    }
    defer client.Disconnect(ctx)

    quickstartDatabase := client.Database("quickstart")
    testCollection := quickstartDatabase.Collection("test")
    testCollection.InsertMany(ctx, stmts) // This is giving error
}

The compiler gives the error cannot use stmts (variable of type []Statement) as []interface{} value in argument to testCollection.InsertMany at the InsertMany command.

I have tried marshalling the struct before inserting using bson.Marshal but even that doesn't work. How do I insert this data into the DB?

3
  • 1
    Have you tried creating a list of interface{} and cast your Statement? Something like: interfaceStmts := []interface{}{} for _, s := range stmts{ interfaceStmts = append(interfaceStmts, s) } Commented Feb 28, 2021 at 18:06
  • @Mihai Yes, that worked. Thank you. But doesn't iterate over every element in the array? Which is the fastest way to do this? Commented Feb 28, 2021 at 18:22
  • 1
    It does iterate over the elements in the array unfortunately. There is no nice and easy way to do the conversion. I think the good news is that the big O complexity of the code will not change with this extra iteration since the lib will also iterate over the batch so complexity is still O(n). This post stackoverflow.com/questions/12753805/… should cover the reason behind the language design. Commented Feb 28, 2021 at 21:09

2 Answers 2

5

insertMany accept []interface{}

i would make like this

newValue := make([]interface{}, len(statements))

for i := range statements {
  newValue[i] = statements[i]
}

col.InsertMany(ctx, newValue)
Sign up to request clarification or add additional context in comments.

1 Comment

Note: if you make using len(statements), then the first len(statements) records will be nil in newValue
0

Faster solution:

s := []any{statements}
col.InsertMany(ctx, s)

Comments

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.