复合运算符
Overview
在本指南中,您可以了解如何执行复合操作。
复合操作会将读取和写入操作组合为单个操作。如果您分别执行读取和写入操作,那么其他人可能会在这两个操作之间更改文档。MongoDB 通过在复合操作期间对您正在修改的文档放置写锁来防止这种情况。
MongoDB 支持以下复合操作:
提示
如果需要读取和写入多个文档,请使用事务。
样本数据
本部分的示例使用以下 Course
结构作为 courses
集合中文档的模型:
type Course struct { Title string Enrollment int32 }
要运行本部分中的示例,请使用以下代码段将样本数据加载到 db.courses
集合中:
coll := client.Database("db").Collection("courses") docs := []interface{}{ Course{Title: "Representation Theory", Enrollment: 40}, Course{Title: "Early Modern Philosophy", Enrollment: 25}, Course{Title: "Animal Communication", Enrollment: 18}, } result, err := coll.InsertMany(context.TODO(), docs)
每个文档均包含某一大学课程的说明,其中包括课程标题和最大注册人数,而它们分别对应于每个文档中的 title
和enrollment
字段。
提示
不存在的数据库和集合
如果执行写操作时不存在必要的数据库和集合,服务器会隐式创建这些数据库和集合。
查找和删除
FindOneAndDelete()
方法查找与指定查询筛选器匹配的第一个文档并将其删除。 该方法返回包含已删除文档的SingleResult
。
注意
FindOneAndDelete()
方法是一种原子操作,这意味着它可以防止任何其他写入操作更改匹配的文档,直到它完成为止。deleteOne()
方法也是一种原子操作,但与 FindOneAndDelete()
方法的不同之处在于,您不能为匹配的文档指定排序顺序。
如果不需要在单个ACID 事务中查找和删除文档,则可以调用findOne()
方法,然后调用deleteOne()
方法。
修改行为
您可以通过传入 FineOneAndDeleteOptions
来修改 FindOneAndDelete()
方法的行为。如果不指定 FineOneAndDeleteOptions
,则驱动程序将使用每个选项的默认值。
FineOneAndDeleteOptions
类型允许您使用以下方法配置选项:
方法 | 说明 |
---|---|
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 |
例子
以下示例使用 FindOneAndDelete()
方法匹配并删除 enrollment
字段值小于 20 的第一个文档:
filter := bson.D{{"enrollment", bson.D{{"$lt", 20}}}} var deletedDoc Course err := coll.FindOneAndDelete(context.TODO(), filter).Decode(&deletedDoc) if err != nil { panic(err) } res, _ := bson.MarshalExtJSON(deletedDoc, false, false) fmt.Println(string(res))
查找并更新
FindOneAndUpdate()
方法查找与指定查询过滤器匹配的第一个文档,并根据更新文档对其进行更新。此方法会返回包含匹配文档的 SingleResult
。
注意
FindOneAndUpdate()
方法是一种原子操作,这意味着它可以防止任何其他写入操作更改匹配的文档,直到它完成为止。updateOne()
方法也是一种原子操作,但与 FindOneAndUpdate()
方法的不同之处在于,您不能为匹配的文档指定排序顺序。
如果不需要在单个ACID 事务中查找和更新文档,则可以调用findOne()
方法,然后调用updateOne()
方法。
修改行为
您可以通过传入 FineOneAndUpdateOptions
来修改 FindOneAndUpdate()
方法的行为。如果不指定 FineOneAndUpdateOptions
,则驱动程序将使用每个选项的默认值。
FineOneAndUpdateOptions
类型允许您使用以下方法配置选项:
方法 | 说明 |
---|---|
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 |
例子
以下示例使用 FindOneAndUpdate()
方法按顺序执行以下操作:
匹配
title
字段值包含“Modern”的第一个文档将匹配文档的
enrollment
字段值更新为32
返回更新后的文档。
filter := bson.D{{"title", bson.D{{"$regex", "Modern"}}}} update := bson.D{{"$set", bson.D{{"enrollment", 32}}}} opts := options.FindOneAndUpdate().SetReturnDocument(options.After) var updatedDoc Course 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))
查找并替换
FindOneAndReplace()
方法查找与指定查询过滤器匹配的第一个文档,并将其替换为替换文档。此方法返回包含匹配文档的 SingleResult
。
注意
此方法与 ReplaceOne()
方法不同。FindOneAndReplace()
将查找和替换作为单个操作执行,并消除了某人在两个操作之间更改文档的可能性。
修改行为
您可以通过传入 FineOneAndReplaceOptions
来修改 FindOneAndReplace()
方法的行为。如果不指定 FineOneAndReplaceOptions
,则驱动程序将使用每个选项的默认值。
FineOneAndReplaceOptions
类型允许您使用以下方法配置选项:
方法 | 说明 |
---|---|
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 |
例子
以下示例使用 FindOneAndReplace()
方法按顺序执行以下操作:
匹配
title
为“Representation Theory”的第一个文档用新文档替换匹配的文档,其中
title
是“组合理论”,enrollment
是35
filter := bson.D{{"title", "Representation Theory"}} replacement := Course{Title: "Combinatorial Theory", Enrollment: 35} var outdatedDoc Course err := coll.FindOneAndReplace(context.TODO(), filter, replacement).Decode(&previousDoc) if err != nil { panic(err) } res, _ := bson.MarshalExtJSON(outdatedDoc, false, false) fmt.Println(string(res))
更多信息
要了解有关执行上述操作的更多信息,请参阅以下指南:
API 文档
要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: