Docs 菜单
Docs 主页
/ / /
Go 驱动程序
/ /

复合运算符

在此页面上

  • 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)

每个文档均包含某一大学课程的说明,其中包括课程标题和最大注册人数,而它们分别对应于每个文档中的 titleenrollment 字段。

提示

不存在的数据库和集合

如果执行写操作时不存在必要的数据库和集合,服务器会隐式创建这些数据库和集合。

FindOneAndDelete()方法查找与指定查询筛选器匹配的第一个文档并将其删除。 该方法返回包含已删除文档的SingleResult

注意

FindOneAndDelete() 方法是一种原子操作,这意味着它可以防止任何其他写入操作更改匹配的文档,直到它完成为止。deleteOne() 方法也是一种原子操作,但与 FindOneAndDelete() 方法的不同之处在于,您不能为匹配的文档指定排序顺序。

要在单独的操作中查找和删除文档,请调用
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))
{"title":"Animal Communication","enrollment":18}

FindOneAndUpdate() 方法查找与指定查询过滤器匹配的第一个文档,并根据更新文档对其进行更新。此方法会返回包含匹配文档的 SingleResult

注意

FindOneAndUpdate() 方法是一种原子操作,这意味着它可以防止任何其他写入操作更改匹配的文档,直到它完成为止。updateOne() 方法也是一种原子操作,但与 FindOneAndUpdate() 方法的不同之处在于,您不能为匹配的文档指定排序顺序。

要查找文档并在单独的操作中更新文档,请调用 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))
{"title":"Early Modern Philosophy","enrollment":32}

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 是“组合理论”,enrollment35

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))
{"title":"Representation Theory","enrollment":40}

要了解有关执行上述操作的更多信息,请参阅以下指南:

要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档:

后退

批量操作