更新文档中的数组
概述
在本指南中,您可以学习如何在单个或多个文档中更新数组元素。
要更新数组中的元素,请执行以下操作
提供更新文档,指定更新内容。
指定要更新的数组元素。
使用具有这些规范的更新操作执行更新。
示例数据
本指南中的示例使用以下Drink
结构体作为 drinks
集合中文档的模型
type Drink struct { Description string Sizes []int32 `bson:"sizes,truncate"` Styles []string }
The truncate
struct tag 允许驱动程序在反序列化时将类型如 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 文档