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

MongoDBの$unwind演算子でサブドキュメント(配列要素)ごとにドキュメントを分割する方法

MongoDBでは、$unwind演算子を使うことで、配列フィールド(サブドキュメント)を持つ1つのドキュメントを、配列の要素ごとに複数のドキュメントへ分割できます。この記事では、実際のコード例を通して具体的な手順をわかりやすく解説します。

1. コレクションの作成とドキュメントの登録

まず、insertOne()メソッドを使って、配列フィールド「Subjects」を含むドキュメントをコレクションに挿入します。

> db.demo276.insertOne({"Name":"Chris","Subjects":["MySQL","MongoDB"]});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e48f953dd099650a5401a51")
}

2. find()メソッドでドキュメントを確認する

find()メソッドを使うと、コレクション内のすべてのドキュメントを表示できます。

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

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

{
   "_id" : ObjectId("5e48f953dd099650a5401a51"),
   "Name" : "Chris",
   "Subjects" : [
      "MySQL",
      "MongoDB"
   ]
}

このように、「Chris」というユーザーのドキュメントには、「MySQL」と「MongoDB」の2つの科目が配列として格納されています。

3. $unwindでドキュメントを分割する

サブドキュメント(配列要素)ごとにドキュメントを分割するには、aggregate()フレームワーク内で$unwindを使用します。

> db.demo276.aggregate( [ { $unwind : "$Subjects" } ] )

実行すると、以下のように配列の要素ごとにドキュメントが分割されて出力されます。

{ "_id" : ObjectId("5e48f953dd099650a5401a51"), "Name" : "Chris", "Subjects" : "MySQL" }
{ "_id" : ObjectId("5e48f953dd099650a5401a51"), "Name" : "Chris", "Subjects" : "MongoDB" }

まとめ

$unwindは、集計パイプライン(aggregation pipeline)の中で配列フィールドを展開するための演算子です。1つの配列にN個の要素が含まれている場合、$unwindを適用すると各要素が独立したドキュメントとして出力され、それ以降のパイプラインステージ($matchや$groupなど)で要素単位の集計やフィルタリングが容易になります。配列データを扱う集計処理において非常に頻繁に使われる重要な機能なので、ぜひ使い方をマスターしておきましょう。

  1. MongoDBでネストしたサブドキュメントをフィルタリングする方法(aggregateと$unwind活用)

    MongoDBでは、配列の中にさらに配列(サブドキュメント)がネストしている構造を持つドキュメントから、特定の条件に合致する要素だけを抽出したいケースがあります。このような場合、aggregate()メソッドと$unwind演算子を組み合わせることで実現できます。本記事では、実際のコード例を使いながら、ネストしたサブドキュメントのフィルタリング手順を解説します。サンプルコレクションの作成まず、ネストしたサブドキュメントを含むドキュメントを挿入して、コレクションを作成しましょう。> db.demo583.insert([ ... { ... details1 : [

  2. MongoDBでサブドキュメントを配列に追加し続ける方法($push演算子の使い方)

    MongoDBで既存のドキュメント内にある配列にサブドキュメントを追加し続けたい場合は、$push 演算子を使用します。ドキュメントを更新する際には update() メソッドと組み合わせて使います。本記事では、実際のコード例を通じて具体的な手順を解説します。1. コレクションの作成とドキュメントの挿入まず、insertOne() メソッドを使ってコレクションを作成し、ドキュメントを挿入します。> db.demo587.insertOne({id:101,details:[{Name:Chris,Age:21,Marks:57}]}); { acknowledged : true,