go – Golang. MongoDB bulkWrite() to update slice of documents-ThrowExceptions

Exception or error:

I have a slice of objects I want to save to Mongo collection. Let’s say

type (
    User struct {
        AccountId       string
        Name            string
        FamilyName      string
        EmailAddress    string
    }
)

func persistUsers(ctx context.Context, db *mongo.Collection, users []User) {

}

Some users are already saved, some – aren’t. I want to upsert the slice. Hence I have two question:

  1. How can I user mongo.Collection.BulkWrite()? I can’t find obvious explanation how to put slice of objects into it.

  2. How do mongo decides what is new, what is old and has to be updated? According to _id?

How to solve:

How can I use mongo.Collection.BulkWrite()?

This example code is based on MongoDB Go driver v1.1.2. First you need to import the following:

"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/bson"

And below is the example code for Collection.BulkWrite and utilises your User struct example:

collection := client.Database("databaseName").Collection("collectionName")

var operations []mongo.WriteModel

// Example using User struct
userA := User{AccountId:"1", Name:"John", FamilyName:"Smith", EmailAddress:"john@example.org"}

operationA := mongo.NewUpdateOneModel()
operationA.SetFilter(bson.M{"AccountId": userA.AccountId}) 
operationA.SetUpdate(bson.M{"Name":userA.Name, 
                            "FamilyName":userA.FamilyName, 
                            "EmailAddress":userA.EmailAddress})
// Set Upsert flag option to turn the update operation to upsert
operationA.SetUpsert(true) 
operations = append(operations, operationA)

// Example using bson.M{}
operationB := mongo.NewUpdateOneModel()
operationB.SetFilter(bson.M{"AccountId":2}) 
operationB.SetUpdate(bson.M{"Name":"Jane", 
                              "FamilyName":"Smith", 
                              "EmailAddress":"jane@example.org"})
operationB.SetUpsert(true) 
operations = append(operations, operationB)

// Specify an option to turn the bulk insertion in order of operation
bulkOption := options.BulkWriteOptions{}
bulkOption.SetOrdered(true)

result, err := collection.BulkWrite(context.TODO(), operations, &bulkOption)
if err != nil {
        log.Fatal(err)
}
fmt.Println(result)

For more information please see:

How do mongo decides what is new, what is old and has to be updated?

If there is no document matches the query criteria (the filter), then update() inserts a single document. If there are documents that match the query criteria it becomes an update. See also Upsert Behaviour for more information.

If your update query criteria contains _id with dot notation, please see Upsert With Dotted _id Query.

Leave a Reply

Your email address will not be published. Required fields are marked *