批量操作
Overview
在本指南中,您可以学习;了解如何使用MongoDB Go驱动程序执行批量操作。批量操作通过在单个方法中执行多个写入操作来减少对服务器的调用次数。
Collection
和 Client
类均提供 BulkWrite()
方法。您可以使用 Collection.BulkWrite()
方法对单个集合执行多个写入操作。您可以使用 Client.BulkWrite()
方法跨多个命名空间执行批量写入。在MongoDB中,命名空间由数据库名称和集合名称组成。
重要
客户端批量写入服务器要求
要对 Client
实例执行批量操作,请确保您的应用程序连接到MongoDB Server v8.0 或更高版本
样本数据
本指南中的示例使用以下结构体:
Book
结构体,它对db.books
集合中的文档进行建模。每个文档都包含一本书的描述,其中包括标题、作者和页长。Poem
结构体,它对db.poems
集合中的文档进行建模。每个文档都包含一首诗的描述,其中包括标题、作者和出版年份。
type Book struct { Title string Author string Length int32 } type Poem struct { Title string Author string Year int32 }
要运行本指南中的示例,请使用以下代码段将示例数据加载到 books
和 poems
集合中:
bookColl := client.Database("db").Collection("books") poemColl := client.Database("db").Collection("poems") books := []interface{}{ Book{Title: "My Brilliant Friend", Author: "Elena Ferrante", Length: 331}, Book{Title: "Lucy", Author: "Jamaica Kincaid", Length: 103}, } poems := []interface{}{ Poem{Title: "Song of Myself", Author: "Walt Whitman", Year: 1855}, Poem{Title: "The Raincoat", Author: "Ada Limon", Year: 2018}, } bookInsert, err := bookColl.InsertMany(context.TODO(), books) poemInsert, err := poemColl.InsertMany(context.TODO(), poems)
提示
不存在的数据库和集合
如果执行写操作时不存在必要的数据库和集合,服务器会隐式创建这些数据库和集合。
集合批量写入
要对单个命名空间执行批量操作,请对集合调用 BulkWrite()
方法,并将 WriteModel 文档大量作为参数传递。
定义集合批量写入模型
要为一个命名空间上的批量操作定义写入操作,请为每个插入、替换、更新或删除创建一个 WriteModel
。
InsertOneModel
要为批量写入定义插入操作,请创建一个 InsertOneModel
,指定要插入的文档。要插入多个文档,请为要插入的每个文档创建一个 InsertOneModel
。
您可以使用以下方法指定 InsertOneModel
的行为:
方法 | 说明 |
---|---|
| The document to insert. |
以下示例创建了两个 InsertOneModel
实例,以将两个文档插入到 books
集合中:
models := []mongo.WriteModel{ mongo.NewInsertOneModel().SetDocument(Book{Title: "Beloved", Author: "Toni Morrison", Length: 324}), mongo.NewInsertOneModel().SetDocument(Book{Title: "Outline", Author: "Rachel Cusk", Length: 258}), }
ReplaceOneModel
要为批量写入定义替换操作,请创建一个 ReplaceOneModel
,指定要替换的文档和替换文档。要替换多个文档,请为每个要替换的文档创建一个 ReplaceOneModel
。
您可以使用以下方法指定 ReplaceOneModel
的行为:
方法 | 说明 |
---|---|
| The type of language collation to use when sorting results. |
| The query filter specifying which document to replace. |
| The index to use to scan for documents. |
| The document to replace the matched document with. |
| The sort order for matching documents. The replace operation
replaces only the first document according to the sort criteria. |
| Whether to insert a new document if the query filter doesn't match any documents. |
以下示例创建一个 ReplaceOneModel
来替换 books
集合中 title
值为 "Lucy"
的文档:
models := []mongo.WriteModel{ mongo.NewReplaceOneModel().SetFilter(bson.D{{"title", "Lucy"}}). SetReplacement(Book{Title: "On Beauty", Author: "Zadie Smith", Length: 473}), }
UpdateOneModel 和 UpdateManyModel
要定义批量写入的更新操作,请创建一个 UpdateOneModel
,指定要更新的文档和一个更新文档。要更新多个文档,请使用 UpdateManyModel
。
您可以使用以下方法指定每个更新模型的行为:
方法 | 说明 |
---|---|
| The array elements the update applies to. |
| The type of language collation to use when sorting results. |
| The query filter specifying which document to update. |
| The index to use to scan for documents. |
| The criteria to use when ordering matching documents.
This method is only available for the UpdateOneModel
class. |
| The modifications to apply on the matched documents. |
| Whether to insert a new document if the query filter doesn't match any documents. |
以下示例创建一个 UpdateOneModel
来更新books
集合中的文档,如果 author
为 "Elena Ferrante"
,则将文档的 length
递减 15
:
models := []mongo.WriteModel{ mongo.NewUpdateOneModel().SetFilter(bson.D{{"author", "Elena Ferrante"}}). SetUpdate(bson.D{{"$inc", bson.D{{"length", -15}}}}), }
DeleteOneModel 和 DeleteManyModel
要为批量写入定义删除操作,请创建 DeleteOneModel
,指定要删除的文档。要删除多个文档,请使用 DeleteManyModel
。
您可以使用以下方法指定每个删除模型的行为:
方法 | 说明 |
---|---|
| The type of language collation to use when sorting results. |
| The query filter specifying which document to delete. |
| The index to use to scan for documents. |
以下示例创建一个 DeleteManyModel
来删除books
集合中 length
大于 300
的文档:
models := []mongo.WriteModel{ mongo.NewDeleteManyModel().SetFilter(bson.D{{"length", bson.D{{"$gt", 300}}}}), }
修改集合级行为
要修改批量写入操作的行为,请将 BulkWriteOptions
实例传递给 BulkWrite()
方法。
BulkWriteOptions
类型允许您使用以下方法来配置选项:
方法 | 说明 |
---|---|
| Specifies whether the operation can opt-out of document level validation. Default: false |
| Specifies a comment to attach to the operation. Default: nil |
| |
| Specifies whether the driver stops performing write operations after an error occurs. Default: true |
集合级返回值
BulkWrite()
方法返回 BulkWriteResult
类型,其中包括有关批量操作的信息。
BulkWriteResult
类型包含以下属性:
集合级执行顺序
要指定批量写入是否按顺序执行操作,可以将 Ordered
选项设立为布尔值。要设立此选项,请指定 BulkWriteOptions
实例的 Ordered
字段。
已排序
默认下,BulkWrite()
方法会按照您添加的顺序运行批量操作,并在出现错误时停止。
提示
这相当于将 true
值传递给 SetOrdered()
方法,如以下代码所示:
opts := options.BulkWrite().SetOrdered(true)
无序
要以任意顺序运行批量写入操作并在发生错误时继续,请将 false
值传递给 SetOrdered()
方法。该方法会在操作完成后报告错误。
以下示例按任意顺序执行以下动作:
插入两个文档
将
title
为“My Brilliant Friend”的新文档替换为新文档如果当前
length
值小于200
,则将每个文档的length
按10
递增删除
author
字段值包含"Jam"
的所有文档
models := []mongo.WriteModel{ mongo.NewInsertOneModel().SetDocument(Book{Title: "Middlemarch", Author: "George Eliot", Length: 904}), mongo.NewInsertOneModel().SetDocument(Book{Title: "Pale Fire", Author: "Vladimir Nabokov", Length: 246}), mongo.NewReplaceOneModel().SetFilter(bson.D{{"title", "My Brilliant Friend"}}). SetReplacement(Book{Title: "Atonement", Author: "Ian McEwan", Length: 351}), mongo.NewUpdateManyModel().SetFilter(bson.D{{"length", bson.D{{"$lt", 200}}}}). SetUpdate(bson.D{{"$inc", bson.D{{"length", 10}}}}), mongo.NewDeleteManyModel().SetFilter(bson.D{{"author", bson.D{{"$regex", "Jam"}}}}), } // Specifies that the bulk write is unordered opts := options.BulkWrite().SetOrdered(false) // Runs the bulk write operation and prints a summary of the // data changes results, err := bookColl.BulkWrite(context.TODO(), models, opts) if err != nil { panic(err) } fmt.Printf("Number of documents inserted: %d\n", results.InsertedCount) fmt.Printf("Number of documents replaced or updated: %d\n", results.ModifiedCount) fmt.Printf("Number of documents deleted: %d\n", results.DeletedCount)
Number of documents inserted: 2 Number of documents replaced or updated: 2 Number of documents deleted: 1
批量操作后,books
(图书)集合中存在以下文档:
{"title":"Atonement","author":"Ian McEwan","length":351} {"title":"Middlemarch","author":"George Eliot","length":904} {"title":"Pale Fire","author":"Vladimir Nabokov","length":246}
客户端批量写入
要跨多个命名空间执行批量操作,请在客户端上调用 BulkWrite()
方法并将 ClientWriteModel 文档大量作为参数传递。
定义客户端批量写入模型
要为多个命名空间上的批量操作指定写入操作,请为每个 insert、replace、 更新或删除创建一个 ClientWriteModel
。将每个写入模型传递给 ClientBulkWrite
结构并指定目标数据库和集合,如以下代码所示:
writes := []mongo.ClientBulkWrite{ {"<database name>", "<collection name>", <write model>}, ... }
ClientInsertOneModel
要为批量写入定义插入操作,请创建 ClientInsertOneModel
以指定要插入的文档。要插入多个文档,请为要插入的每个文档创建一个 ClientInsertOneModel
。
您可以使用以下方法指定 ClientInsertOneModel
的行为:
方法 | 说明 |
---|---|
| The document to insert. |
以下示例创建了两个 ClientInsertOneModel
实例,以将一个文档插入到 books
集合中,并将一个文档插入到 poems
集合中:
bookInsertDoc := Book{Title: "Parable of the Sower", Author: "Octavia E. Butler", Length: 320} poemInsertDoc := Poem{Title: "Fame is a fickle food", Author: "Emily Dickinson", Year: 1659} writes := []mongo.ClientBulkWrite{ {"db", "books", mongo.NewClientInsertOneModel().SetDocument(bookInsertDoc)}, {"db", "poems", mongo.NewClientInsertOneModel().SetDocument(poemInsertDoc)}, }
ClientReplaceOneModel
要为批量写入定义替换操作,请创建一个 ClientReplaceOneModel
,指定要替换的文档和替换文档。要替换多个文档,请为每个要替换的文档创建一个 ClientReplaceOneModel
。
您可以使用以下方法指定 ClientReplaceOneModel
的行为:
方法 | 说明 |
---|---|
| The type of language collation to use when sorting results. |
| The query filter specifying which document to replace. |
| The index to use to scan for documents. |
| The document to replace the matched document with. |
| The sort order for matching documents. The replace operation
replaces only the first document according to the sort criteria. |
| Whether to insert a new document if the query filter doesn't match any documents. |
此示例创建 ClientReplaceOneModel
实例来定义以下操作:
对
books
集合执行替换操作,替换title
值为"Lucy"
的文档对
poems
集合执行替换操作,替换title
值为"Song of Myself"
的文档
writes := []mongo.ClientBulkWrite{ {"db", "books", mongo.NewClientReplaceOneModel(). SetFilter(bson.D{{"title", "Lucy"}}). SetReplacement(Book{Title: "On Beauty", Author: "Zadie Smith", Length: 473})}, {"db", "poems", mongo.NewClientReplaceOneModel(). SetFilter(bson.D{{"title", "Song of Myself"}}). SetReplacement(Poem{Title: "America", Author: "Walt Whitman", Year: 1888})}, }
ClientUpdateOneModel 和 ClientUpdateManyModel
要定义批量写入的更新操作,请创建一个 ClientUpdateOneModel
,指定要更新的文档和一个更新文档。要更新多个文档,请使用 ClientUpdateManyModel
。
您可以使用以下方法指定每个更新模型的行为:
方法 | 说明 |
---|---|
| The array elements the update applies to. |
| The type of language collation to use when sorting results. |
| The query filter specifying which document to update. |
| The index to use to scan for documents. |
| The criteria to use when ordering matching documents.
This method is only available for the ClientUpdateOneModel class. |
| The modifications to apply on the matched documents. |
| Whether to insert a new document if the query filter
doesn't match any documents. |
此示例创建 ClientUpdateOneModel
实例来定义以下操作:
对
books
集合进行更新操作,以更新author
值为"Elena Ferrante"
的文档对
poems
集合进行更新操作,以更新author
值为"Ada Limon"
的文档
writes := []mongo.ClientBulkWrite{ {"db", "books", mongo.NewClientUpdateOneModel(). SetFilter(bson.D{{"author", "Elena Ferrante"}}). SetUpdate(bson.D{{"$inc", bson.D{{"length", -15}}}})}, {"db", "poems", mongo.NewClientUpdateOneModel(). SetFilter(bson.D{{"author", "Ada Limon"}}). SetUpdate(bson.D{{"author", "Ada Limón"}})}, }
注意
要更新与上示例中的 author
字段查询筛选器匹配的所有文档,请使用 ClientUpdateManyModel
实例。
ClientDeleteOneModel 和 ClientDeleteManyModel
要为批量写入定义删除操作,请创建 ClientDeleteOneModel
,指定要删除的文档。要删除多个文档,请使用 ClientDeleteManyModel
。
您可以使用以下方法指定每个删除模型的行为:
方法 | 说明 |
---|---|
| The type of language collation to use when sorting results. |
| The query filter specifying which document to delete. |
| The index to use to scan for documents. |
此示例创建 ClientDeleteOneModel
实例来定义以下操作:
对
books
集合执行删除操作,删除length
值为103
的文档对
poems
集合执行删除操作,删除year
值为1855
的文档
writes := []mongo.ClientBulkWrite{ {"db", "books", mongo.NewClientDeleteOneModel(). SetFilter(bson.D{{"length", 103}})}, {"db", "poems", mongo.NewClientDeleteOneModel(). SetFilter(bson.D{{"year", 1855}})}, }
修改客户端级行为
要修改批量写入操作的行为,请将 ClientBulkWriteOptions
实例传递给 BulkWrite()
方法。
ClientBulkWriteOptions
类型允许您使用以下方法来配置选项:
方法 | 说明 |
---|---|
| Specifies whether the operation can opt-out of document level validation. Default: false |
| Specifies whether the driver stops performing write operations after an error occurs. Default: true |
| Specifies a comment to attach to the operation. Default: nil |
| |
| Specifies the write concern for the operations. Default: nil |
| Specifies whether detailed information about each successful operation is
included in the result. Default: false |
客户端级返回值
BulkWrite()
方法返回 ClientBulkWriteResult
类型,其中包括有关批量操作的信息。
ClientBulkWriteResult
类型包含以下属性:
属性 | 说明 |
---|---|
| 插入的文档数量。 |
| 在更新和替换操作中与查询筛选器匹配的文档数量。 |
| 通过更新和替换操作修改的文档数量。 |
| 删除的文档数量。 |
| 通过更新和替换操作更新或插入的文档数量。 |
| 操作索引到每个插入文档的 |
| 操作索引到每个更新文档的 |
| 操作索引到每个已删除文档的 |
| 一个布尔值,表示写入操作是否已确认。 |
| 布尔值,表示结果是否包含详细结果。 |
客户端级执行顺序
要指定批量写入是否按顺序执行操作,可以将 Ordered
选项设立为布尔值。要设立此选项,请指定 ClientBulkWriteOptions
实例的 Ordered
字段。
已排序
默认情况下,BulkWrite()
方法按照您添加的顺序执行批量操作,并在出现错误时停止执行。
提示
这相当于将 true
值传递给 SetOrdered()
方法,如以下代码所示:
opts := options.ClientBulkWrite().SetOrdered(true)
无序
要以任意顺序运行批量写入操作并在发生错误时继续,请将 false
值传递给 SetOrdered()
方法。该方法会在操作完成后报告错误。
以下示例按任意顺序执行以下动作:
将新文档插入到
books
和poems
集合中更新
poems
集合中title
值为"The Raincoat"
的文档替换
books
集合中title
值为"My Brilliant Friend"
的文档
writes := []mongo.ClientBulkWrite{ {"db", "books", mongo.NewClientInsertOneModel(). SetDocument(Book{Title: "Middlemarch", Author: "George Eliot", Length: 904})}, {"db", "poems", mongo.NewClientInsertOneModel(). SetDocument(Poem{Title: "Mad Girl's Love Song", Author: "Sylvia Plath", Year: 1953})}, {"db", "poems", mongo.NewClientUpdateOneModel(). SetFilter(bson.D{{"title", "The Raincoat"}}). SetUpdate(bson.D{{"title", "The Conditional"}})}, {"db", "books", mongo.NewClientReplaceOneModel(). SetFilter(bson.D{{"title", "My Brilliant Friend"}}). SetReplacement(Book{Title: "The Story of a New Name", Author: "Elena Ferrante", Length: 480})}, } opts := options.ClientBulkWrite().SetOrdered(false) results, err := client.BulkWrite(context.TODO(), writes, opts) if err != nil { panic(err) } fmt.Printf("Number of documents inserted: %d\n", results.InsertedCount) fmt.Printf("Number of documents replaced or updated: %d\n", results.ModifiedCount)
Number of documents inserted: 2 Number of documents replaced or updated: 2
更多信息
有关执行批量操作的可运行示例,请参阅执行批量操作。
相关操作
要了解有关执行上述操作的更多信息,请参阅以下指南:
API 文档
要详细学习;了解用于集合批量写入的方法或类型,请参阅以下API文档:
要详细学习;了解用于客户端端批量写入的方法或类型,请参阅以下API文档: