MongoDB
 Computer >> コンピューター >  >> プログラミング >> MongoDB

MongoDBで1つのクエリを使って複数のドキュメントを更新する方法

MongoDBでは、initializeUnorderedBulkOp() を使ったバルク操作を利用することで、1回のリクエストで複数のドキュメント(行)をまとめて更新できます。通常の updateOne()updateMany() は単一の更新条件しか指定できませんが、バルク操作なら異なる条件・異なる更新内容を持つ複数の更新処理をキューに登録し、一括実行することが可能です。

サンプルコレクションの作成

まず、insertOne() メソッドを使ってドキュメントを含むコレクションを作成します。

> db.upDateMultipleRowsDemo.insertOne({"CustomerName":"John","CustomerPurchaseAmount":500});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5cd6ceb06d78f205348bc626")
}
> db.upDateMultipleRowsDemo.insertOne({"CustomerName":"Chris","CustomerPurchaseAmount":700});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5cd6ceb26d78f205348bc627")
}
> db.upDateMultipleRowsDemo.insertOne({"CustomerName":"David","CustomerPurchaseAmount":50});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5cd6ceb36d78f205348bc628")
}
> db.upDateMultipleRowsDemo.insertOne({"CustomerName":"Larry","CustomerPurchaseAmount":1900});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5cd6ceb46d78f205348bc629")
}

登録済みドキュメントの確認

次に、find() メソッドを使ってコレクション内のすべてのドキュメントを表示します。

> db.upDateMultipleRowsDemo.find().pretty();

上記のクエリを実行すると、次のような出力が得られます。

{
   "_id" : ObjectId("5cd6ceb06d78f205348bc626"),
   "CustomerName" : "John",
   "CustomerPurchaseAmount" : 500
}
{
   "_id" : ObjectId("5cd6ceb26d78f205348bc627"),
   "CustomerName" : "Chris",
   "CustomerPurchaseAmount" : 700
}
{
   "_id" : ObjectId("5cd6ceb36d78f205348bc628"),
   "CustomerName" : "David",
   "CustomerPurchaseAmount" : 50
}
{
   "_id" : ObjectId("5cd6ceb46d78f205348bc629"),
   "CustomerName" : "Larry",
   "CustomerPurchaseAmount" : 1900
}

バルク操作による複数ドキュメントの一括更新

ここからが本題です。initializeUnorderedBulkOp() を呼び出してバルクオペレーションビルダーを取得し、find()updateOne() を組み合わせて更新対象ごとの操作を登録します。最後に execute() を呼び出すことで、登録したすべての更新が一括して実行されます。

> var manyUpdateValue = db.upDateMultipleRowsDemo.initializeUnorderedBulkOp();

> manyUpdateValue.find({ _id: ObjectId("5cd6ceb06d78f205348bc626")}).updateOne({$set:{"CustomerName":"Bob" }});

> manyUpdateValue.find({ _id: ObjectId("5cd6ceb36d78f205348bc628")}).updateOne({$set:{"CustomerPurchaseAmount":56544444}});

> manyUpdateValue.execute();
BulkWriteResult({
   "writeErrors" : [ ],
   "writeConcernErrors" : [ ],
   "nInserted" : 0,
   "nUpserted" : 0,
   "nMatched" : 2,
   "nModified" : 2,
   "nRemoved" : 0,
   "upserted" : [ ]
})

実行結果を見ると、nMatchednModified の値がどちらも「2」となっており、2件のドキュメントが正常に更新されたことがわかります。

ポイント: initializeUnorderedBulkOp() は「順序なし」バルク操作を作成します。この場合、各操作の実行順序は保証されず、並列に処理されるため高速です。一方、操作順序を厳密に守りたい場合は initializeOrderedBulkOp() を使用します。

更新結果の確認

もう一度すべてのドキュメントを表示して、更新が正しく反映されているか確認しましょう。

> db.upDateMultipleRowsDemo.find().pretty();

実行すると、次の出力が得られます。

{
   "_id" : ObjectId("5cd6ceb06d78f205348bc626"),
   "CustomerName" : "Bob",
   "CustomerPurchaseAmount" : 500
}
{
   "_id" : ObjectId("5cd6ceb26d78f205348bc627"),
   "CustomerName" : "Chris",
   "CustomerPurchaseAmount" : 700
}
{
   "_id" : ObjectId("5cd6ceb36d78f205348bc628"),
   "CustomerName" : "David",
   "CustomerPurchaseAmount" : 56544444
}
{
   "_id" : ObjectId("5cd6ceb46d78f205348bc629"),
   "CustomerName" : "Larry",
   "CustomerPurchaseAmount" : 1900
}

このように、最初のドキュメントの CustomerName が「Bob」に、3番目のドキュメントの CustomerPurchaseAmount が「56544444」にそれぞれ変更されていることが確認できます。

まとめ

  • initializeUnorderedBulkOp() を使うと、異なる条件での複数の更新を1回の execute() 呼び出しでまとめて実行できる。
  • ネットワークラウンドトリップが1回で済むため、大量のドキュメントを個別に更新するよりもパフォーマンスが大幅に向上する。
  • 実行結果は BulkWriteResult オブジェクトとして返され、マッチ数や更新数などの詳細を確認できる。
  1. MySQLの1つのINSERT文で複数行をまとめて挿入する方法

    はじめにMySQLでは、INSERT文を何度も実行しなくても、1つのクエリで複数の行(レコード)を一度に挿入することができます。VALUES句の後にカンマ区切りで複数の値セットを記述するだけで、効率よくデータを登録できるため、大量の初期データ投入などで非常に便利です。この記事では、実際のSQL例を使いながら、複数行を一括挿入する手順をわかりやすく解説します。1. テーブルを作成するまず、サンプル用のテーブルを作成します。StudentIdはAUTO_INCREMENT付きの主キーとして定義し、レコード追加時に自動的に連番が採番されるようにしています。mysql> create table

  2. MySQLのUPDATE文で1つのクエリを使って複数のレコードを更新する方法

    MySQLでは、UPDATEステートメントを使うことで、1つのクエリで複数のカラムや複数のレコードの値をまとめて更新できます。この記事では、実際にサンプルテーブルを作成し、UPDATE文でデータを更新する具体的な手順を解説します。サンプルテーブルの作成まず、テーブルを作成しましょう。mysql> create table DemoTable     -> (     -> Id int NOT NULL AUTO_INCREMENT PRIMARY KEY,    &