对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

复合运算符

在本指南中,您可以了解如何执行复合操作

复合操作会将读取和写入操作组合为单个操作。如果您分别执行读取和写入操作,那么其他人可能会在这两个操作之间更改文档。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() 方法。

您可以通过传入 FindOneAndDeleteOptions 来修改 FindOneAndDelete() 方法的行为。如果不指定 FindOneAndDeleteOptions,则驱动程序将使用每个选项的默认值。

FindOneAndDeleteOptions 类型允许您使用以下方法配置选项:

方法
说明

SetCollation()

对结果进行排序时要使用的语言排序规则类型。
默认:nil

SetMaxTime()

查询在服务器上运行的最长时间。
默认:nil

SetProjection()

要包含在返回文档中的字段。
默认:nil

SetSort()

对匹配文档进行排序的排序字段和方向。
默认:nil

SetHint()

用于扫描文档的索引。
默认: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() 方法。

您可以通过传入 FindOneAndUpdateOptions 来修改 FindOneAndUpdate() 方法的行为。如果不指定 FindOneAndUpdateOptions,则驱动程序将使用每个选项的默认值。

FindOneAndUpdateOptions 类型允许您使用以下方法配置选项:

方法
说明

SetArrayFilters()

更新应用到的数组元素。
默认:nil

SetBypassDocumentValidation()

是否允许写入操作选择退出文档级验证
默认:false

SetCollation()

对结果进行排序时要使用的语言排序规则类型。
默认:nil

SetMaxTime()

查询在服务器上运行的最长时间。
默认:nil

SetProjection()

要包含在返回文档中的字段。
默认:nil

SetReturnDocument()

是否在 SingleResult 中返回原始或更新的文档。
默认值:options.Before

SetSort()

对匹配文档进行排序的排序字段和方向。
默认:nil

SetUpsert()

如果查询筛选条件不匹配任何文档,是否插入新文档。
默认:false

SetHint()

用于扫描文档的索引。
默认: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() 将查找和替换作为单个操作执行,并且消除了有人在这两个操作之间更改文档的可能性。使用 FindOneAndReplace() 时,您还可以对匹配文档设立排序顺序。

要查找文档并在单独的操作中进行替换,请调用 FindOne() 方法,然后调用 ReplaceOne() 方法。

您可以通过传入 FindOneAndReplaceOptions 来修改 FindOneAndReplace() 方法的行为。如果不指定 FindOneAndReplaceOptions,则驱动程序将使用每个选项的默认值。

FindOneAndReplaceOptions 类型允许您使用以下方法配置选项:

方法
说明

SetBypassDocumentValidation()

是否允许写入操作选择退出文档级验证
默认:false

SetCollation()

对结果进行排序时要使用的语言排序规则类型。
默认:nil

SetMaxTime()

查询在服务器上运行的最长时间。
默认:nil

SetProjection()

要包含在返回文档中的字段。
默认:nil

SetReturnDocument()

是否在 SingleResult 中返回原始文档或替换文档。
默认值:nil

SetSort()

对匹配文档进行排序的排序字段和方向。
默认:nil

SetUpsert()

如果查询筛选条件不匹配任何文档,是否插入新文档。
默认:false

SetHint()

用于扫描文档的索引。
默认: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 文档: