MongoDBのaggregate()で特定のフィールドを持つサブドキュメントだけを絞り込む方法
MongoDBでは、配列内のサブドキュメントから特定のフィールドを持つ要素だけを取り出したいケースがよくあります。そんなときに活躍するのがaggregate()メソッドです。$match・$unwind・$projectというパイプラインステージを組み合わせることで、目的のサブドキュメントだけを効率的に抽出できます。
ここでは、details配列の中から「Name」というフィールドを持つサブドキュメントのみを取得する手順を、実際のコード例とともに解説します。
サンプルデータの作成
まず、insertOne()メソッドを使って、複数のサブドキュメントを含むdetails配列を持つドキュメントをコレクションに挿入します。
> db.demo285.insertOne(
... {
... details : [
... {
... Name : "Chris"
... },
... {
... Name2: "Bob"
... },
... {
... Name: "Mike"
... }
... ]
... }
...)
{
"acknowledged" : true,
"insertedId" : ObjectId("5e4abffef49383b52759cbb9")
}
このサンプルデータには、Nameフィールドを持つサブドキュメントが2つ(ChrisとMike)と、Name2フィールドのみを持つサブドキュメント(Bob)が1つ含まれています。
挿入したドキュメントの確認
find()メソッドを使って、コレクション内のすべてのドキュメントを表示してみましょう。
> db.demo285.find();
実行すると、次のような出力が得られます。
{ "_id" : ObjectId("5e4abffef49383b52759cbb9"), "details" : [ { "Name" : "Chris" }, { "Name2" : "Bob" }, { "Name" : "Mike" } ] }
Nameフィールドを持つサブドキュメントだけを抽出するクエリ
それでは本題です。以下の集計パイプラインを実行すると、指定したフィールド(この例では「Name」)を持つサブドキュメントに絞り込むことができます。
> db.demo285.aggregate(
... [
... { $match:
... {'details.Name' :
... { $exists: 1 }
... }
... },
... { $unwind: "$details" },
... { $match:
... {'details.Name' :
... { $exists: 1 }
... }
... },
... {$project: { Name: "$details.Name", _id: 0 } }
... ])
各ステージの役割
- 最初の $match:
$exists演算子を使い、details配列内にNameフィールドを持つ要素が存在するドキュメントだけを対象にします。これにより、不要なドキュメントを早い段階で除外できます。 - $unwind: details配列を分解し、各サブドキュメントを個別のドキュメントとして扱えるようにします。
- 2番目の $match: 配列分解後の各サブドキュメントに対して再度フィルタリングを行い、Nameフィールドを持つものだけを残します。
- $project: 出力結果に含めるフィールドを指定します。ここではdetails.Nameの値をNameとして出力し、_idフィールドは0を指定して非表示にしています。
実行結果
上記のクエリを実行すると、次のようにNameフィールドを持つサブドキュメントだけが出力されます。Name2しか持っていない「Bob」は正しく除外されている点に注目してください。
{ "Name" : "Chris" }
{ "Name" : "Mike" }
このように、aggregate()パイプラインを活用すれば、配列内のサブドキュメントを柔軟にフィルタリングし、必要なフィールドだけを整形して取得できます。大規模なコレクションでも、最初の$matchで対象を絞り込むことで高いパフォーマンスを維持できるのもポイントです。
-
MongoDBで「_id」以外のすべてのフィールド値を表示するクエリ方法
MongoDBでは、ドキュメントを取得すると自動的に _id フィールドが含まれますが、場合によってはこのフィールドを除外し、他のフィールド値だけを表示したいことがあります。本記事では、コレクションの作成から、_id を除いたすべてのフィールド値を表示するまでの一連の手順を解説します。1. ドキュメントを含むコレクションを作成するまずは、サンプルとなるコレクションを作成しましょう。以下のコマンドを実行して、複数のドキュメントを一括挿入します。> db.demo590.insert([... { "Name": "
-
MongoDBでフィールドの戻り値を制限するクエリの書き方($slice演算子の使い方)
MongoDBでフィールドの戻り値を制限するクエリの書き方MongoDBで配列フィールドの要素数を制限して取得したい場合は、$slice演算子を使用します。この演算子を活用することで、クエリ結果として返す配列の要素数を柔軟にコントロールできます。ここでは、具体的な手順をサンプルコードとともに解説します。1. コレクションとドキュメントの作成まず、insertOne()メソッドを使ってドキュメントを挿入し、コレクションを作成します。> db.demo594.insertOne(... {... &n