Docs Menu

Docs HomeGo

Insert or Update in a Single Operation

On this page

  • Overview
  • Upsert
  • Additional Information

In this guide, you can learn how to perform an upsert.

The examples in this guide use 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 examples 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.


Non-existent Databases and Collections

If the necessary database and collection don't exist when you perform a write operation, the server implicitly creates them.

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()


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.

The following example performs the following actions:

  • Matches documents where the species is "Ledebouria socialis" and the plant_id is 3

  • Updates the height of the matched document to 8.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 {
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}

To learn more about the operations mentioned, see the following guides:

To learn more about any of the methods or types mentioned in this guide, see the following API Documentation:

←  Update Arrays in a DocumentBulk Operations →