Insert or Update in a Single Operation
On this page
Overview
In this guide, you can learn how to perform an upsert.
Sample Data
The example in this guide uses the following Plant
struct as a model for documents
in the plants
collection:
type Plant struct { Species string PlantID int32 `bson:"plant_id"` Height float64 }
To run the example in this guide, load the sample data into the
db.plants
collection with the following snippet:
coll := client.Database("db").Collection("plants") docs := []interface{}{ Plant{Species: "Polyscias fruticosa", PlantID: 1, Height: 27.6}, Plant{Species: "Polyscias fruticosa", PlantID: 2, Height: 34.9}, Plant{Species: "Ledebouria socialis", PlantID: 1, Height: 11.4}, } result, err := coll.InsertMany(context.TODO(), docs)
Each document contains a description of an individual plant that
includes the species, plant ID, and height corresponding to
the species
, plant_id
, and height
fields in each document.
Tip
Nonexistent Databases and Collections
If the necessary database and collection don't exist when you perform a write operation, the server implicitly creates them.
Upsert
Applications use insert and update operations to store and modify data. Sometimes, you need to choose between an insert and an update operation depending on whether the document exists. MongoDB simplifies this decision for us with an upsert option.
An upsert performs one of the following actions:
Updates documents that match your query filter
Inserts a new document if there are no matches to your query filter
You can specify an upsert by passing true
to the SetUpsert()
method in the options of the following write operation methods:
UpdateOne()
UpdateByID()
UpdateMany()
ReplaceOne()
FindOneAndUpdate()
FindOneAndReplace()
Tip
If you don't specify an upsert, no change occurs in the write
operation when zero documents match your query filter. This is
equivalent to passing false
to the SetUpsert()
method.
Example
The following example performs the following actions:
Matches documents where the
species
is "Ledebouria socialis" and theplant_id
is3
Updates the
height
of the matched document to8.3
Inserts this document if there are no matches to the query filter
filter := bson.D{{"species", "Ledebouria socialis"}, {"plant_id", 3}} update := bson.D{{"$set", bson.D{{"species", "Ledebouria socialis"}, {"plant_id", 3}, {"height", 8.3}}}} opts := options.Update().SetUpsert(true) result, err := coll.UpdateOne(context.TODO(), filter, update, opts) if err != nil { panic(err) } fmt.Printf("Number of documents updated: %v\n", result.ModifiedCount) fmt.Printf("Number of documents upserted: %v\n", result.UpsertedCount)
If you query the plants
collection to view all documents, you can
see that since the query filter did not match any documents, a new
document was inserted with the specified fields:
{"species":"Polyscias fruticosa","plant_id":1,"height":27.6} {"species":"Polyscias fruticosa","plant_id":2,"height":34.9} {"species":"Ledebouria socialis","plant_id":1,"height":11.4} {"species":"Ledebouria socialis","plant_id":3,"height":8.3}
Additional Information
To learn more about the operations mentioned, see the following guides:
API Documentation
To learn more about any of the methods or types mentioned in this guide, see the following API Documentation: