MongoDBでサブドキュメントの値を基準にソートする方法(アグリゲーション活用)
MongoDBでサブドキュメントの一致を基準にソートする方法
配列内のサブドキュメント(ネストされたドキュメント)の値を基準にデータを並べ替えたい場合は、アグリゲーションフレームワークを利用するのが最適です。通常のfind()メソッドでは直接対応できないため、$match・$unwind・$sortなどのパイプラインステージを組み合わせて実現します。ここでは、実際のコード例をもとに手順をわかりやすく解説します。
1. サンプルコレクションの作成
まず、insertOne()メソッドを使って学生情報のドキュメントを2件登録します。「StudentDetails」フィールドは配列構造になっており、各要素が「Age(年齢)」と「StudentScore(スコア)」を持つサブドキュメントです。
> db.sortBySubDocumentsDemo.insertOne(
{
"StudentName": "Chris",
"StudentDetails": [
{
"Age":21,
"StudentScore":91
},
{
"Age":22,
"StudentScore":99
},
{
"Age":21,
"StudentScore":93
}
]
}
);
{
"acknowledged" : true,
"insertedId" : ObjectId("5cd57e297924bb85b3f48942")
}
> db.sortBySubDocumentsDemo.insertOne(
{
"StudentName": "Robert",
"StudentDetails": [
{
"Age":24,
"StudentScore":78
},
{
"Age":21,
"StudentScore":86
},
{
"Age":23,
"StudentScore":45
}
]
}
);
{
"acknowledged" : true,
"insertedId" : ObjectId("5cd57e4c7924bb85b3f48943")
}
2. 登録したドキュメントの確認
find()メソッドにpretty()を組み合わせると、コレクション内のすべてのドキュメントを整形された形式で確認できます。
> db.sortBySubDocumentsDemo.find().pretty();
実行すると、次のような出力が得られます。
{
"_id" : ObjectId("5cd57e297924bb85b3f48942"),
"StudentName" : "Chris",
"StudentDetails" : [
{
"Age" : 21,
"StudentScore" : 91
},
{
"Age" : 22,
"StudentScore" : 99
},
{
"Age" : 21,
"StudentScore" : 93
}
]
}
{
"_id" : ObjectId("5cd57e4c7924bb85b3f48943"),
"StudentName" : "Robert",
"StudentDetails" : [
{
"Age" : 24,
"StudentScore" : 78
},
{
"Age" : 21,
"StudentScore" : 86
},
{
"Age" : 23,
"StudentScore" : 45
}
]
}
3. サブドキュメントの値でソートするクエリ
それでは本題となる、「StudentScore(スコア)」の昇順でソートするクエリを見ていきましょう。以下のパイプラインでは、年齢が21歳のサブドキュメントだけを対象に、スコア順に並べ替えています。
> db.sortBySubDocumentsDemo.aggregate([
{$match: { 'StudentDetails.Age': 21 }},
{$unwind: '$StudentDetails'},
{$match: {'StudentDetails.Age': 21}},
{$project: {_id: 0, "StudentName": 1, 'StudentDetails.StudentScore': 1}},
{$sort: { 'StudentDetails.StudentScore': 1 }},
{$limit: 5}
]);
各パイプラインステージの役割は次のとおりです。
- $match(1回目): 配列内にAgeが21のサブドキュメントを持つドキュメントだけを抽出します。
- $unwind: 配列「StudentDetails」を分解し、要素ごとに個別のドキュメントへ展開します。
- $match(2回目): 展開後のサブドキュメントから、改めてAgeが21のものだけを絞り込みます。
- $project: 出力するフィールドを指定します(_idを除外し、StudentNameとStudentScoreを保持)。
- $sort: StudentScoreを昇順(1)で並べ替えます。
- $limit: 結果を最大5件に制限します。
4. 実行結果
クエリを実行すると、年齢21歳のサブドキュメントがスコアの昇順に出力されます。
{ "StudentName" : "Robert", "StudentDetails" : { "StudentScore" : 86 } }
{ "StudentName" : "Chris", "StudentDetails" : { "StudentScore" : 91 } }
{ "StudentName" : "Chris", "StudentDetails" : { "StudentScore" : 93 } }
このように、アグリゲーションパイプラインを活用すれば、配列内のサブドキュメントの値を条件として抽出し、思い通りの順序でソートできます。ネストされたデータ構造を扱う際にぜひ覚えておきたいテクニックなので、実際のプロジェクトでも活用してみてください。
-
MongoDBでサブドキュメント内の配列に含まれる_idと一致するドキュメントを照会する方法
MongoDBでは、あるコレクションのサブドキュメント内にある配列の値(idなど)を取得し、その値を使って別のコレクションの_idと一致するドキュメントを照会できます。この記事では、$in演算子とdistinct()メソッドを組み合わせた実践的な方法を解説します。 1. 基準となるコレクションを作成する まず、照合条件となる_idのリストを持つコレクションを作成します。ここでは、サブドキュメントの配列を含むドキュメントを挿入します。 > db.demo568.insertOne({ _id: 101, details: [ {id : 101 }, { id:103 } ] }); {
-
MongoDBで配列の値を使ってコレクションを並べ替える方法
MongoDBのコレクションを配列の値を基準にソートしたい場合は、aggregate()メソッドと $sort ステージを組み合わせて使用します。さらに、配列を個々のドキュメントに分解するために $unwind も活用します。 サンプルコレクションの作成 まず、ドキュメントを含むコレクションを作成しましょう。ここでは、学生ごとの詳細情報(名前とスコア)を配列として持つドキュメントを挿入します。 > db.demo577.insertOne( ... { ... student: { ... details: [ ... { .