Compound Operations
Overview
In this guide, you can learn how to perform compound operations.
Compound operations combine a read and write operation into a single operation. If you perform a read and write operation separately, there's a chance someone else may alter the document between both operations. MongoDB prevents this by placing a write lock on the document you are modifying for the duration of your compound operation.
MongoDB supports the following compound operations:
Tip
If you need to read and write to more than one document, use transactions.
Sample Data
Run the following snippet to load the documents into the tea.ratings
collection:
coll := client.Database("tea").Collection("ratings") docs := []interface{}{ bson.D{{"type", "Masala"}, {"rating", 10}}, bson.D{{"type", "Assam"}, {"rating", 5}}, bson.D{{"type", "Oolong"}, {"rating", 7}}, bson.D{{"type", "Earl Grey"}, {"rating", 8}}, bson.D{{"type", "English Breakfast"}, {"rating", 5}}, } result, err := coll.InsertMany(context.TODO(), docs) if err != nil { panic(err) } fmt.Printf("Number of documents inserted: %d\n", len(result.InsertedIDs))
Tip
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.
Each document contains a rating for a type of tea that corresponds to
the type
and rating
fields.
Note
Each example truncates the ObjectID
value because the driver
generates them uniquely.
Find and Delete
The FindOneAndDelete()
method finds the first document that matches
the specified query filter and deletes it. The method returns a
SingleResult
containing the deleted document.
Note
This method differs from the DeleteOne()
method.
FindOneAndDelete()
performs a find and delete as a single
operation, and eliminates the possibility of someone altering a
document between both operations.
Modify Behavior
You can modify the behavior of the FindOneAndDelete()
method by
passing in a FineOneAndDeleteOptions
. If you don't specify a
FineOneAndDeleteOptions
, the driver uses the default values for each
option.
The FineOneAndDeleteOptions
type allows you to configure options
with the following methods:
Method | Description |
---|---|
SetCollation() | The type of language collation to use when sorting results. Default: nil |
SetMaxTime() | The maximum amount of time that the query can run on the server. Default: nil |
SetProjection() | The fields to include in the document returned. Default: nil |
SetSort() | The sort fields and directions to order the documents matched. Default: nil |
SetHint() | The index to use to scan for documents. Default: nil |
Example
The following example matches and deletes a document where the type
is "Assam" with the FindOneAndDelete()
method:
filter := bson.D{{"type", "Assam"}} var deletedDoc bson.D err := coll.FindOneAndDelete(context.TODO(), filter).Decode(&deletedDoc) if err != nil { panic(err) } fmt.Println(deletedDoc)
Find and Update
The FindOneAndUpdate()
method finds the first document that matches
the specified query filter and updates it according to the update
document. The method returns a SingleResult
containing the matched
document.
Note
This method differs from the UpdateOne()
method.
FindOneAndUpdate()
performs a find and update as a single
operation, and eliminates the possibility of someone altering a
document between both operations.
Modify Behavior
You can modify the behavior of the FindOneAndUpdate()
method by
passing in a FineOneAndUpdateOptions
. If you don't specify a
FineOneAndUpdateOptions
, the driver uses the default values for each
option.
The FineOneAndUpdateOptions
type allows you to configure options
with the following methods:
Method | Description |
---|---|
SetArrayFilters() | The array elements the update applies to. Default: nil |
SetBypassDocumentValidation() | Whether to allow the write operation to opt-out of document level validation. Default: false |
SetCollation() | The type of language collation to use when sorting results. Default: nil |
SetMaxTime() | The maximum amount of time that the query can run on the server. Default: nil |
SetProjection() | The fields to include in the document returned. Default: nil |
SetReturnDocument() | Whether to return the original or updated document in the SingleResult .Default: options.Before |
SetSort() | The sort fields and directions to order the documents matched. Default: nil |
SetUpsert() | Whether to insert a new document if the query filter doesn't match any documents. Default: false |
SetHint() | The index to use to scan for documents. Default: nil |
Example
The following example performs the following actions in order with the
FindOneAndUpdate()
method:
Matches a document where the
type
is "Oolong"Updates the matched document's
rating
to9
Returns the updated document
filter := bson.D{{"type", "Oolong"}} update := bson.D{{"$set", bson.D{{"rating", 9}}}} opts := options.FindOneAndUpdate().SetReturnDocument(options.After) var updatedDoc bson.D err := coll.FindOneAndUpdate(context.TODO(), filter, update, opts).Decode(&updatedDoc) if err != nil { panic(err) } fmt.Println(updatedDoc)
Find and Replace
The FindOneAndReplace()
method finds the first document that
matches the specified query filter and replaces it with the replacement
document. The method returns a SingleResult
containing the matched
document.
Note
This method differs from the ReplaceOne()
method.
FindOneAndReplace()
performs a find and replace as a single
operation, and eliminates the possibility of someone altering a
document between both operations.
Modify Behavior
You can modify the behavior of the FindOneAndReplace()
method by
passing in a FineOneAndReplaceOptions
. If you don't specify a
FineOneAndReplaceOptions
, the driver uses the default values for each
option.
The FineOneAndReplaceOptions
type allows you to configure options
with the following methods:
Method | Description |
---|---|
SetBypassDocumentValidation() | Whether to allow the write operation to opt-out of document level validation. Default: false |
SetCollation() | The type of language collation to use when sorting results. Default: nil |
SetMaxTime() | The maximum amount of time that the query can run on the server. Default: nil |
SetProjection() | The fields to include in the document returned. Default: nil |
SetReturnDocument() | Whether to return the original or replaced document in the SingleResult .Default: nil |
SetSort() | The sort fields and directions to order the documents matched. Default: nil |
SetUpsert() | Whether to insert a new document if the query filter doesn't match any documents. Default: false |
SetHint() | The index to use to scan for documents. Default: nil |
Example
The following example performs the following actions in order with the
FindOneAndReplace()
method:
Matches a document where the
type
is "English Breakfast"Replaces the matched document with a new document where the
type
is "Ceylon" andrating
is6
filter := bson.D{{"type", "English Breakfast"}} replacement := bson.D{{"type", "Ceylon"}, {"rating", 6}} var previousDoc bson.D err := coll.FindOneAndReplace(context.TODO(), filter, replacement).Decode(&previousDoc) if err != nil { panic(err) } fmt.Println(previousDoc)
Additional Information
To learn more about performing the operations mentioned, see the following guides:
API Documentation
To learn more about any of the methods or types discussed in this guide, see the following API Documentation: