Overview
このガイドでは、 MongoDB Go Driver を使用して 一括操作 を実行する方法を学習できます。一括操作では、単一のメソッドで複数の書込み (write) 操作を実行することで、サーバーへの呼び出し回数を減らします。
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)
Tip
存在しないデータベースとコレクション
書き込み操作を実行するときに必要なデータベースとコレクションが存在しない場合は、サーバーが暗黙的にそれらを作成します。
コレクションの一括書込み (write)
単一の名前空間に対して一括操作を実行するには、コレクションで BulkWrite()
メソッドを呼び出し、WriteModel ドキュメントの配列をパラメーターとして渡します。
コレクション一括書込みモデルを定義する
1 つの名前空間に対する一括操作の書込み操作を定義するには、挿入、置換、更新、または削除ごとに WriteModel
を作成します。
InsertOneModel
一括書き込みの挿入操作を定義するには、挿入するドキュメントを指定する InsertOneModel
を作成します。複数のドキュメントを挿入するには、挿入するドキュメントごとに InsertOneModel
を作成します。
次の方法を使用して、InsertOneModel
の動作を指定できます。
方式 | 説明 |
---|---|
| The document to insert. |
次の例では、2 つの InsertOneModel
インスタンスを作成して、2 つのドキュメントを 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. |
次の例では、title
の値が "Lucy"
である books
コレクション内のドキュメントを置き換えるために ReplaceOneModel
を作成します。
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. |
次の例では、length
が 300
より大きい books
コレクション内のドキュメントを削除するために DeleteManyModel
を作成します。
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
フィールドを指定します。
ordered
デフォルトでは 、BulkWrite()
メソッドは一括操作を追加した順序で実行し、エラーが発生した場合は停止します。
Tip
これは、次のコードに示すように、true
の値を SetOrdered()
メソッドに渡すことと同じです。
opts := options.BulkWrite().SetOrdered(true)
順序なし
一括書き込み操作を任意の順序で実行し、エラーが発生した場合に続行するには、false
の値を SetOrdered()
メソッドに渡します。メソッドは、操作完了後にエラーを報告します。
次の例では、次のアクションを任意の順序で実行します。
2 つのドキュメントを挿入します
title
が「My Billian MongoDB」であるドキュメントを新しいドキュメントに置き換えます現在の
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}
一括操作の例: フルファイル
注意
セットアップ例
この例では、接続 URI を使用してMongoDBのインスタンスに接続します。MongoDBインスタンスへの接続の詳細については、MongoClient の作成 ガイドを参照してください。この例では、Atlasサンプルデータセットに含まれる sample_restaurants
データベースの restaurants
コレクションも使用します。「Atlas を使い始める」ガイドに従って、 MongoDB Atlasの無料階層のデータベースにロードできます。
次の例は、次のアクションを実行する完全に実行可能なファイルです。
name
フィールド値が"Towne Cafe"
であるドキュメントに一致し、name
フィールド値が"New Towne Cafe"
に設定され、cuisine
フィールド値が"French"
に設定されている新しいドキュメントに置き換えます。name
フィールド値がRiviera Caterer
であるドキュメントに一致し、name
フィールド値を"Riviera Cafe"
に更新します
// Runs bulk write operations on a collection by using the Go driver package main import ( "context" "fmt" "log" "os" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options" ) // Defines a Restaurant struct as a model for documents in the "restaurants" collection type Restaurant struct { Name string RestaurantId string `bson:"restaurant_id,omitempty"` Cuisine string `bson:"cuisine,omitempty"` Address interface{} `bson:"address,omitempty"` Borough string `bson:"borough,omitempty"` Grades []interface{} `bson:"grades,omitempty"` } func main() { if err := godotenv.Load(); err != nil { log.Println("No .env file found") } var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/ja-jp/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) if err != nil { panic(err) } defer func() { if err = client.Disconnect(context.TODO()); err != nil { panic(err) } }() coll := client.Database("sample_restaurants").Collection("restaurants") // Creates write models that specify replace and update operations models := []mongo.WriteModel{ mongo.NewReplaceOneModel().SetFilter(bson.D{{"name", "Towne Cafe"}}). SetReplacement(Restaurant{Name: "New Towne Cafe", Cuisine: "French"}), mongo.NewUpdateOneModel().SetFilter(bson.D{{"name", "Riviera Caterer"}}). SetUpdate(bson.D{{"$set", bson.D{{"name", "Riviera Cafe"}}}}), } // Specifies that the bulk write is ordered opts := options.BulkWrite().SetOrdered(true) // Runs a bulk write operation for the specified write operations results, err := coll.BulkWrite(context.TODO(), models, opts) if err != nil { panic(err) } // When you run this file for the first time, it should print output similar to the following: // Number of documents replaced or modified: 2 fmt.Printf("Number of documents replaced or modified: %d", results.ModifiedCount) }
Number of documents matched: 2 Number of documents modified: 2
クライアント一括書込み (write)
複数の名前空間で一括操作を実行するには、クライアントで BulkWrite()
メソッドを呼び出し、ClientWriteModel ドキュメントの配列をパラメーターとして渡します。
クライアント一括書込みモデルの定義
複数の名前空間に対する一括操作の書込み操作を指定するには、挿入、置換、更新、または削除ごとに ClientWriteModel
を作成します。次のコードに示すように、各書き込みモデルを ClientBulkWrite
構造体に渡し、ターゲットのデータベースとコレクションを指定します。
writes := []mongo.ClientBulkWrite{ {"<database name>", "<collection name>", <write model>}, ... }
ClientInsertOneModel
一括書き込みの挿入操作を定義するには、挿入するドキュメントを指定する ClientInsertOneModel
を作成します。複数のドキュメントを挿入するには、挿入するドキュメントごとに ClientInsertOneModel
を作成します。
次の方法を使用して、ClientInsertOneModel
の動作を指定できます。
方式 | 説明 |
---|---|
| The document to insert. |
次の例では、2 つの ClientInsertOneModel
インスタンスを作成し、1 つのドキュメントをbooks
コレクションに挿入し、2 つのドキュメントを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
インスタンスを作成しています。
title
値が"Lucy"
であるドキュメントを置き換えるには、books
コレクションの操作を置き換えますtitle
値が"Song of Myself"
であるドキュメントを置き換えるには、poems
コレクションの操作を置き換えます
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
型には次のプロパティが含まれています。
プロパティ | 説明 |
---|---|
| 挿入されたドキュメントの数。 |
| アップデート操作と置換操作でクエリフィルターに一致したドキュメントの数。 |
| 更新操作と置換操作によって変更されたドキュメントの数。 |
| 削除されたドキュメントの数。 |
| 更新操作と置換操作によってアップサートされたドキュメントの数。 |
| 挿入された各ドキュメントの |
| アップデートされた各ドキュメントの |
| 各削除されたドキュメントの |
| 書込み (write)操作が確認されたかどうかを示すブール値値。 |
| 結果に詳細な結果が含まれているかどうかを示すブール値値。 |
クライアントレベルの実行順序
一括書き込みで操作が順番に実行されるかどうかを指定するには、Ordered
オプションをブール値値に設定します。このオプションを設定するには、ClientBulkWriteOptions
インスタンスの Ordered
フィールドを指定します。
ordered
デフォルトでは、 BulkWrite()
メソッドは一括操作を追加した順序で実行され、エラーが発生した場合は停止します。
Tip
これは、次のコードに示すように、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ドキュメントを参照してください。