更新文档中的数组
Overview
在本指南中,您可以学习如何更新一个或多个文档中的数组元素。
要更新数组中的元素,请执行以下操作:
提供指定更新的更新文档。
指定要更新的数组元素。
使用具有这些规范的更新操作执行更新。
样本数据
本部分的示例使用以下 Drink
结构作为 drinks
集合中文档的模型:
type Drink struct { Description string Sizes []int32 `bson:"sizes,truncate"` Styles []string }
truncate
结构标记允许驱动程序在解组时将 float64
等类型截断为 int32
。
要运行本部分中的示例,请使用以下代码段将样本数据加载到 db.drinks
集合中:
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)
每个文档包含饮料描述,其中包括饮料说明、可用的规格(盎司)以及可用的制备方式,分别对应于每个文档中的 description
、sizes
和 styles
字段。
提示
不存在的数据库和集合
如果执行写操作时不存在必要的数据库和集合,服务器会隐式创建这些数据库和集合。
以下示例使用 FindOneAndUpdate()
方法检索和更新文档,并在更新后返回文档的状态。如果要使用数组字段更新多个文档,请使用 UpdateMany()
方法。
指定数组元素
要指定要更新的数组元素,请使用位置运算符。 位置操作符可以指定要更新的第一个、多个或所有数组元素。
要使用位置运算符指定数组元素,请使用点符号。点符号是一种属性访问语法,用于导航嵌入文档的数组元素和字段。
第一个数组元素
若要更新与查询筛选器匹配的第一个数组元素,请使用位置 $
运算符。查询筛选器必须用于数组字段。
例子
此示例将执行以下动作:
匹配
sizes
中值小于或等于16
的数组元素。递减与
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"]}
注意
查询筛选器与值12
和16
匹配。 由于该操作首先匹配12
,因此它会递减。 如果要更新两个匹配的值,请参阅多个数组元素。
多个数组元素
要更新与查询筛选器匹配的多个数组元素,请使用筛选后的位置 $[<identifier>]
运算符。您必须在更新操作中包含数组筛选器以指定要更新的数组元素。
<identifier>
是您在数组筛选器中使用的名称。此值必须以小写字母开头,并且只能包含字母数字字符。
例子
此示例将执行以下动作:
创建一个带有名为
hotOptions
的标识符的数组筛选器,以匹配包含 “hot” 的数组元素。使用
SetArrayFilters()
方法应用数组筛选器。删除这些数组元素。
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","",""]}
所有数组元素
要更新所有数组元素,请使用全位置 $[]
操作符。
注意
如果指定了数组字段的查询筛选器,位置 $[]
操作符会忽略该查询筛选器,并更新所有数组元素。
例子
此示例将 sizes
中的每个数组元素乘以 29.57
,以将盎司转换为毫升:
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"]}
更多信息
要了解有关本指南中讨论的操作的更多信息,请参阅以下指南:
API 文档
要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: