MongoDBで複数のドキュメントを一括アップサートする方法
はじめに
MongoDBでは、update()メソッドにupsert()オプションを組み合わせることで、条件に一致するドキュメントを更新し、一致するドキュメントが存在しない場合には新規挿入(インサート)を行うことができます。この操作は「アップサート」と呼ばれます。
さらに、大量のドキュメントを効率的に処理したい場合は、initializeUnorderedBulkOp()によるバルク操作を利用すると便利です。本記事では、実際のコード例を通じて、複数ドキュメントの一括アップサートの手順を解説します。
サンプルコレクションの作成
まずは、ドキュメントを含むコレクションを作成します。ここではinsertOne()メソッドを使って、4件のドキュメントを挿入します。
> db.demo425.insertOne({"Name":"Chris","Age":21});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e74ee4fbbc41e36cc3cae6c")
}
> db.demo425.insertOne({"Name":"David","Age":23});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e74ee56bbc41e36cc3cae6d")
}
> db.demo425.insertOne({"Name":"Chris","Age":21});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e74ee57bbc41e36cc3cae6e")
}
> db.demo425.insertOne({"Name":"Chris","Age":21});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e74ee5cbbc41e36cc3cae6f")
}
登録済みドキュメントの確認
find()メソッドを使用して、コレクション内のすべてのドキュメントを表示してみましょう。
> db.demo425.find();
上記のクエリを実行すると、次のような出力が得られます。
{ "_id" : ObjectId("5e74ee4fbbc41e36cc3cae6c"), "Name" : "Chris", "Age" : 21 }
{ "_id" : ObjectId("5e74ee56bbc41e36cc3cae6d"), "Name" : "David", "Age" : 23 }
{ "_id" : ObjectId("5e74ee57bbc41e36cc3cae6e"), "Name" : "Chris", "Age" : 21 }
{ "_id" : ObjectId("5e74ee5cbbc41e36cc3cae6f"), "Name" : "Chris", "Age" : 21 }
「Chris」という名前のドキュメントが3件登録されていることが確認できます。
複数ドキュメントの一括アップサート
続いて、MongoDBで複数のドキュメントをアップサートするクエリを見ていきましょう。initializeUnorderedBulkOp()でバルク操作を初期化し、find()で対象となるドキュメントを指定したうえで、upsert().update()を実行します。
> var b1 = db.demo425.initializeUnorderedBulkOp();
> b1.find( { Name: "Chris" } ).upsert().update(
... {
... $setOnInsert: { id:101},
... $set: { Name: "Robert", Age:23 }
... }
... );
> b1.execute();
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 0,
"nUpserted" : 0,
"nMatched" : 3,
"nModified" : 3,
"nRemoved" : 0,
"upserted" : [ ]
})
ポイント:$setOnInsert と $set の違い
このクエリでは、2種類の更新演算子を使い分けています。
- $setOnInsert:ドキュメントが新規挿入される場合にのみ適用されるフィールドを指定します。既存ドキュメントの更新時には無視されます。
- $set:既存ドキュメントの更新時にも適用されるフィールドを指定します。
今回の例では、「Name」が「Chris」である3件のドキュメントがすべて条件に一致したため、結果は nMatched: 3、nModified: 3 となり、新規挿入(アップサート)は発生していません(nUpserted: 0)。
アップサート後の結果確認
もう一度find()メソッドですべてのドキュメントを表示し、結果を確認します。
> db.demo425.find();
実行結果は以下のとおりです。
{ "_id" : ObjectId("5e74ee4fbbc41e36cc3cae6c"), "Name" : "Robert", "Age" : 23 }
{ "_id" : ObjectId("5e74ee56bbc41e36cc3cae6d"), "Name" : "David", "Age" : 23 }
{ "_id" : ObjectId("5e74ee57bbc41e36cc3cae6e"), "Name" : "Robert", "Age" : 23 }
{ "_id" : ObjectId("5e74ee5cbbc41e36cc3cae6f"), "Name" : "Robert", "Age" : 23 }
「Chris」だった3件のドキュメントがすべて「Robert」(Age: 23)に更新されていることがわかります。一方、「David」のドキュメントは検索条件に一致しないため、そのまま変更されていません。
まとめ
MongoDBで複数のドキュメントを一括アップサートするには、initializeUnorderedBulkOp()でバルク操作を初期化し、find(条件).upsert().update(更新内容)の形式で指定します。条件に一致するドキュメントは更新され、一致しない場合は$setOnInsertや$setで指定した内容が新規挿入されます。大量データの効率的な更新・挿入が必要な場面で、ぜひ活用してみてください。
-
MongoDBでnull値を除外してドキュメントを取得する方法($ne演算子の使い方)
MongoDBでコレクション内のnull値を無視(除外)してドキュメントを取得したい場合、aggregate()の中で「$ne : null」を使用します。この記事では、実際にサンプルコレクションを作成し、null値を除外するクエリの書き方をステップごとに解説します。 1. サンプルコレクションの作成 まず、insertOne()メソッドを使って、配列フィールドに空文字・通常の文字列・nullが混在したドキュメントを持つコレクションを作成します。 > db.demo722.insertOne( ... { ... id:101, ... detail
-
MongoDBで1つのクエリを使って複数のドキュメントを一括更新する方法(bulkWrite活用ガイド)
MongoDBで1つのクエリで複数のドキュメントを更新するには?MongoDBで1回のリクエスト(1つのクエリ)で複数のドキュメントを効率的に更新したい場合は、bulkWrite()メソッドを使用します。bulkWrite()は、複数の書き込み操作(insert、update、deleteなど)をまとめてサーバーに送信できるため、個別にクエリを発行するよりもパフォーマンス面で優れています。ここでは、updateOne操作を組み合わせて、複数のドキュメントのフィールドを一度に更新する手順を具体的に解説します。1. コレクションの作成とドキュメントの挿入まず、insertOne()メソッドを使って