Update Arrays in a Document
On this page
Overview
In this guide, you can learn how to update array elements in one or more documents.
To update elements in an array, perform the following actions:
Provide an update document that specifies the update.
Specify which array elements to update.
Perform the update using an update operation with these specifications.
Sample Data
The examples in this guide use the following Drink
struct as a model for documents
in the drinks
collection:
type Drink struct { Description string Sizes []int32 `bson:"sizes,truncate"` Styles []string }
The truncate
struct tag allows the driver
to truncate types such as float64
to int32
when unmarshalling.
To run the examples in this guide, load the sample data into the
db.drinks
collection with the following snippet:
coll := client.Database("db").Collection("drinks") docs := []interface{}{ Drink{Description: "Matcha Latte", Sizes: []int32{12, 16, 20}, Styles: []string{"iced", "hot", "extra hot"}}, } result, err := coll.InsertMany(context.TODO(), docs)
Each document contains a description of a drink that
includes the drink's description, available sizes in ounces, and available
preparation styles, corresponding to the description
, sizes
, and
styles
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.
The following examples use the FindOneAndUpdate()
method to
retrieve and update a document and to return the state of the document
after the update occurs. If you want to update multiple documents with
an array field, use the UpdateMany()
method.
Specify Array Elements
To specify which array elements to update, use a positional operator. Positional operators can specify the first, multiple, or all array elements to update.
To specify array elements with a positional operator, use dot notation. Dot notation is a property access syntax for navigating array elements and fields of an embedded document.
First Array Element
To update the first array element that matches your query filter, use
the positional $
operator. The query filter must be for the array
field.
Example
This example performs the following actions:
Matches array elements in
sizes
where the value is less than or equal to16
.Decrements the first array value matched by
2
.
filter := bson.D{{"sizes", bson.D{{"$lte", 16}}}} update := bson.D{{"$inc", bson.D{{"sizes.$", -2}}}} opts := options.FindOneAndUpdate(). SetReturnDocument(options.After) var updatedDoc Drink err := coll.FindOneAndUpdate(context.TODO(), filter, update, opts).Decode(&updatedDoc) if err != nil { panic(err) } res, _ := bson.MarshalExtJSON(updatedDoc, false, false) fmt.Println(string(res))
{"description":"Matcha Latte","sizes":[10,16,20],"styles":["iced","hot","extra hot"]}
Note
The query filter matches the values 12
and 16
. Since the
operation matches 12
first, it is decremented. If you want to update
both matched values, see Multiple Array Elements.
Multiple Array Elements
To update multiple array elements that match your query filter, use the
filtered positional $[<identifier>]
operator. You must include an
array filter in your update operation to specify which array elements to
update.
The <identifier>
is the name you use within your array filter. This
value must begin with a lowercase letter and only contain alphanumeric
characters.
Example
This example performs the following actions:
Creates an array filter with an identifier called
hotOptions
to match array elements that contain "hot".Applies the array filter using the
SetArrayFilters()
method.Removes these array elements.
identifier := []interface{}{bson.D{{"hotOptions", bson.D{{"$regex", "hot"}}}}} update := bson.D{{"$unset", bson.D{{"styles.$[hotOptions]", ""}}}} opts := options.FindOneAndUpdate(). SetArrayFilters(options.ArrayFilters{Filters: identifier}). SetReturnDocument(options.After) var updatedDoc Drink err := coll.FindOneAndUpdate(context.TODO(), bson.D{}, update, opts).Decode(&updatedDoc) if err != nil { panic(err) } res, _ := bson.MarshalExtJSON(updatedDoc, false, false) fmt.Println(string(res))
{"description":"Matcha Latte","sizes":[12,16,20],"styles":["iced","",""]}
All Array Elements
To update all the array elements, use the all positional $[]
operator.
Note
If you specify a query filter for the array field, the positional
$[]
operator ignores the query filter and updates all the array
elements.
Example
This example multiplies every array element in sizes
by 29.57
to convert from ounces to milliliters:
update := bson.D{{"$mul", bson.D{{"sizes.$[]", 29.57}}}} opts := options.FindOneAndUpdate(). SetReturnDocument(options.After) var updatedDoc Drink err := coll.FindOneAndUpdate(context.TODO(), bson.D{}, update, opts).Decode(&updatedDoc) if err != nil { panic(err) } res, _ := bson.MarshalExtJSON(updatedDoc, false, false) fmt.Println(string(res))
{"description":"Matcha Latte","sizes":[354,473,591],"styles":["iced","hot","extra hot"]}
Additional Information
To learn more about the operations discussed in this guide, 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: