MongoDBで別のフィールドごとにグループ化した値を検索する方法
MongoDBで別のフィールドごとにグループ化した値を検索する方法
MongoDBであるフィールドの値を、別のフィールドを基準にグループ化して取得したい場合には、アグリゲーションパイプラインの$groupと$projectを組み合わせて使用します。この記事では、実際にコレクションを作成し、「名前(Name)」ごとに「趣味(HobbyDetails)」をまとめる例を通じて、具体的な手順をわかりやすく解説します。
サンプルコレクションの作成
まず、insertOne()メソッドを使って、ドキュメントを含むコレクションを作成しましょう。
> db.demo374.insertOne(
... {
... "Name" : "Chris",
... "HobbyDetails" : [
... "Reading Book",
... "Playing Football"
... ],
... "CountryName" : "US"
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5e5a04402ae06a1609a00b04")
}
> db.demo374.insertOne(
... {
... "Name" : "Chris",
... "HobbyDetails" : [
... "Browsing Internet",
... "Playing Football"
... ],
... "CountryName" : "US"
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5e5a04402ae06a1609a00b05")
}登録済みドキュメントの確認
find()メソッドを使用すると、コレクション内のすべてのドキュメントを表示できます。
> db.demo374.find();
上記のクエリを実行すると、次のような出力が得られます。
{ "_id" : ObjectId("5e5a04402ae06a1609a00b04"), "Name" : "Chris", "HobbyDetails" : [ "Reading Book", "Playing Football" ], "CountryName" : "US" }
{ "_id" : ObjectId("5e5a04402ae06a1609a00b05"), "Name" : "Chris", "HobbyDetails" : [ "Browsing Internet", "Playing Football" ], "CountryName" : "US" }別のフィールドでグループ化して値を検索するクエリ
以下は、NameフィールドをキーとしてHobbyDetailsの値をグループ化し、取得するアグリゲーションクエリです。
> db.demo374.aggregate([
... {$match : { "CountryName" : "US"}},
... {$group : {"_id" : "$Name", "HobbyDetails" : {$addToSet : "$HobbyDetails"}}},
... {$project : {"_id" : 0, "Name" : "$_id", "HobbyDetails" : {$reduce : {input : "$HobbyDetails", initialValue : [], in: { $concatArrays : ["$$value", "$$this"] }}}}}
... ]).pretty()このパイプラインでは、各ステージが次のような役割を担っています。
- $match:
CountryNameが「US」のドキュメントのみを抽出します。 - $group:
Nameフィールドをキーにドキュメントをグループ化し、$addToSetによって趣味の配列を収集します。 - $project:出力形式を整形し、
$reduceと$concatArraysを組み合わせて、ネストした複数の配列を1つのフラットな配列へと結合します。
実行結果
上記のクエリを実行すると、次のような出力が得られます。
{
"Name" : "Chris",
"HobbyDetails" : [
"Browsing Internet",
"Playing Football",
"Reading Book",
"Playing Football"
]
}このように、同じ「Chris」という名前を持つ複数のドキュメントから、趣味の情報が1つの配列にまとめられました。$addToSetは配列そのものを重複なく集約しますが、各配列の内部に含まれる値(ここでは「Playing Football」)の重複までは自動的に除去されない点に注意してください。完全に重複を排除したい場合は、$reduceの結果に対して$setUnionを適用する方法も有効です。また、$addToSetは要素の順序を保証しないため、出力順序が必要な場合は最後に$sortなどで整列することをおすすめします。
-
MongoDBでオブジェクトの配列フィールドの値をクエリする方法
MongoDBでは、配列型のフィールドに格納された値を、通常のフィールドと同じように簡単に検索できます。配列内のいずれかの要素が指定した値と一致すれば、そのドキュメントがクエリ結果として返されます。 サンプルコレクションの作成 まず、ドキュメントを含むコレクションを作成しましょう。ここでは「status」という配列フィールドを持つドキュメントを挿入します。 > db.demo295.insertOne({status:[Active,Inactive]}); { acknowledged : true, insertedId : ObjectId(5e4d4ea65d9326
-
MongoDBで真偽値(true/false)を条件にドキュメントを検索する方法
MongoDBでフィールドの有無や値の状態をもとにドキュメントを検索したい場合、find()メソッドと$exists演算子を組み合わせるのが効果的です。ネストされた配列内のフィールドを調べる際には、ドット表記(dot notation)を使用します。この記事では、実際のコード例を通して、配列内の特定フィールドが存在しないドキュメントを抽出する方法を解説します。1. サンプルコレクションの作成まず、テスト用のコレクション「demo367」を作成し、2つのドキュメントを挿入します。片方のドキュメントにはdetails.Subjectフィールドが存在し、もう片方には存在しない構造になっています。&g