【MongoDB】配列内のすべてのオブジェクトが特定の値を持つドキュメントを検索する方法
MongoDBで配列内のすべてのオブジェクトが特定の値を持つドキュメントを検索する方法
MongoDBでは、配列フィールドに含まれるすべてのオブジェクトが特定の値を持っているかどうかを確認したいケースがあります。例えば、「学生の受講情報リストの中で、すべての要素が『Active』ステータスであるドキュメントだけを抽出したい」といった場合です。
このような条件を実現するには、$not 演算子と $elemMatch を組み合わせます。「特定の値以外を持つ要素が1つも存在しない」ことを条件にすることで、「すべての要素がその値である」という意味になります。以下、具体的な手順を見ていきましょう。
1. コレクションの作成とドキュメントの挿入
まず、insertOne() メソッドを使ってサンプルコレクションを作成します。1つ目のドキュメントは「InActive」の要素を含み、2つ目のドキュメントはすべての要素が「Active」になっています。
> db.demo74.insertOne(
... {
... StudentName: "Chris",
... StudentDetails: [{
... "Subject": "MongoDB",
... "isRegular": "Active"
... },{
... "Subject": "MongoDB",
... "isRegular": "InActive"
... },{
... "Subject": "MongoDB",
... "isRegular": "InActive"
... }]
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5e29c6b671bf0181ecc4226f")
}
> db.demo74.insertOne({
... StudentName: "David",
... StudentDetails: [{
... "Subject": "MongoDB",
... "isRegular": "Active"
... },{
... "Subject": "MongoDB",
... "isRegular": "Active"
... },{
... "Subject": "MongoDB",
... "isRegular": "Active"
... }]
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5e29c6b771bf0181ecc42270")
}
2. find()メソッドですべてのドキュメントを表示
find() メソッドを使うと、コレクション内のすべてのドキュメントを確認できます。
> db.demo74.find();
このクエリを実行すると、次のような出力が得られます。
{
"_id" : ObjectId("5e29c6b671bf0181ecc4226f"), "StudentName" : "Chris", "StudentDetails" : [
{ "Subject" : "MongoDB", "isRegular" : "Active" },
{ "Subject" : "MongoDB", "isRegular" : "InActive" },
{ "Subject" : "MongoDB", "isRegular" : "InActive" }
]
}
{
"_id" : ObjectId("5e29c6b771bf0181ecc42270"), "StudentName" : "David", "StudentDetails" : [
{ "Subject" : "MongoDB", "isRegular" : "Active" },
{ "Subject" : "MongoDB", "isRegular" : "Active" },
{ "Subject" : "MongoDB", "isRegular" : "Active" }
]
}
3. 配列内のすべてのオブジェクトが特定の値を持つドキュメントを検索するクエリ
ここからが本題です。$not と $elemMatch、さらに $ne を組み合わせた次のクエリを使用します。
> db.demo74.find({ "StudentDetails": { "$not": { "$elemMatch": { "isRegular": { $ne: "Active" } } } }, "StudentDetails.isRegular": "Active" }).pretty();
このクエリのロジックを分解すると、次のようになります。
- "isRegular": { $ne: "Active" } … 「Active 以外の値を持つ要素」を定義します。
- $elemMatch … 配列の中に、上記の条件に一致する要素が存在するかどうかを判定します。
- $not … その存在を否定します。つまり「Active 以外の要素が1つもない=すべて Active」という意味になります。
- "StudentDetails.isRegular": "Active" … 配列フィールドが存在し、少なくとも1つの要素が Active であること(空配列やフィールド欠落を除外)を保証します。
実際の実行結果は次のとおりです。
{
"_id" : ObjectId("5e29c6b771bf0181ecc42270"),
"StudentName" : "David",
"StudentDetails" : [
{
"Subject" : "MongoDB",
"isRegular" : "Active"
},
{
"Subject" : "MongoDB",
"isRegular" : "Active"
},
{
"Subject" : "MongoDB",
"isRegular" : "Active"
}
]
}
ご覧のとおり、「InActive」を含む Chris のドキュメントは除外され、すべての要素が「Active」である David のドキュメントのみが返されました。
まとめ
配列内のすべてのオブジェクトが特定の値を持つドキュメントを検索したい場合は、{ フィールド名: { $not: { $elemMatch: { キー: { $ne: 対象値 } } } }, "フィールド名.キー": 対象値 } というパターンを使います。このテクニックは、ステータス管理やフラグの一括チェックなど、さまざまな場面で活用できるので、ぜひ覚えておきましょう。
-
MongoDBでオブジェクト配列内の特定のネストされたドキュメントをクエリする方法
MongoDBでオブジェクトの配列からネストされたドキュメントを抽出する オブジェクトの配列に格納されたネストされたドキュメントを条件付きで検索したい場合、find()メソッドに$elemMatch演算子を組み合わせることで、指定した条件に一致する要素だけを取り出すことができます。 ここでは、「StudentAge」フィールドを持つ学生情報だけを配列から抽出する例を見ていきましょう。 1. サンプルコレクションの作成 まず、ドキュメントを挿入してコレクションを作成します。このコレクションには、学生情報がオブジェクトの配列として格納されています。 > db.demo763.insertO
-
MongoDBで配列をクエリして特定の値を取得する方法
配列から特定の値を取得するには、aggregate()メソッドと$projectステージを組み合わせて使用します。まずは、ドキュメントを含むコレクションを作成してみましょう。 > db.demo761.insertOne( ... { ... "details": [ ... { ... "