MongoDBで配列のすべての要素が特定の値を持つドキュメントを検索する方法
MongoDBで配列内の要素を条件にドキュメントを照合するには、$elemMatch 演算子を使用します。本記事では、配列のすべての要素が特定の値(この例では86)と一致するドキュメントを抽出する方法を、実際のコード例とともに解説します。
1. サンプルコレクションの作成
まず、テスト用のコレクションを作成し、ドキュメントを挿入します。insertOne() メソッドを使って、Details フィールドに Score を持つオブジェクトの配列を格納した3件のドキュメントを登録します。
> db.demo15.insertOne({"Details":[{"Score":56},{"Score":78}]});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e0f7806d7df943a7cec4fab")
}
> db.demo15.insertOne({"Details":[{"Score":86},{"Score":86}]});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e0f7817d7df943a7cec4fac")
}
> db.demo15.insertOne({"Details":[{"Score":97},{"Score":85}]});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e0f7823d7df943a7cec4fad")
}
この時点で、コレクションには以下のようなデータが格納されています。
- 1件目:Score が「56」と「78」(条件に一致しない)
- 2件目:Score が「86」と「86」(両方とも条件に一致)
- 3件目:Score が「97」と「85」(条件に一致しない)
2. 登録したドキュメントの確認
find() メソッドを使って、コレクション内のすべてのドキュメントを表示してみましょう。
> db.demo15.find();
実行すると、次のような出力が得られます。
{ "_id" : ObjectId("5e0f7806d7df943a7cec4fab"), "Details" : [ { "Score" : 56 }, { "Score" : 78 } ] }
{ "_id" : ObjectId("5e0f7817d7df943a7cec4fac"), "Details" : [ { "Score" : 86 }, { "Score" : 86 } ] }
{ "_id" : ObjectId("5e0f7823d7df943a7cec4fad"), "Details" : [ { "Score" : 97 }, { "Score" : 85 } ] }
3. 配列の全要素が特定の値と一致するドキュメントを検索する
ここが本題です。「配列内のすべての要素が特定の値(86)を持つ」ドキュメントを検索するには、$exists・$not・$elemMatch・$ne を組み合わせたクエリを使用します。
> db.demo15.find({
... "Details.Score" : {
... $exists : true
... },
... "Details" : {
... $not : {
... $elemMatch : {
... "Score" : {
... $ne : 86
... }
... }
... }
... }
... });
クエリの仕組み
このクエリは、一見複雑に見えますが、論理的にシンプルな構造になっています。
- "Details.Score": { $exists: true } —
Details配列内にScoreフィールドが存在することを確認します。これにより、フィールド自体を持たないドキュメントが誤ってマッチするのを防ぎます。 - Details: { $not: { $elemMatch: { Score: { $ne: 86 } } } } — 「Score が 86 以外の要素を1つでも持つ配列」を除外します。結果として、残るのはすべての要素の Score が 86 である配列だけになります。
このように「否定の否定」を使うことで、「すべての要素が条件を満たす」という要件を実現しています。
実行結果
上記のクエリを実行すると、次の出力が得られます。
{ "_id" : ObjectId("5e0f7817d7df943a7cec4fac"), "Details" : [ { "Score" : 86 }, { "Score" : 86 } ] }
期待どおり、2件目のドキュメント(すべての Score が 86 のもの)だけが返されました。
まとめ
MongoDBで「配列のすべての要素が特定の値と一致する」ドキュメントを検索するには、$elemMatch と $ne を $not で包む手法が有効です。さらに $exists を組み合わせることで、対象フィールドが存在するドキュメントのみを確実に絞り込めます。配列データの厳密なバリデーションや検索が必要な場面で、ぜひ活用してみてください。
-
MongoDBで配列をクエリして特定の値を取得する方法
配列から特定の値を取得するには、aggregate()メソッドと$projectステージを組み合わせて使用します。まずは、ドキュメントを含むコレクションを作成してみましょう。 > db.demo761.insertOne( ... { ... "details": [ ... { ... "
-
Pythonで「値がk以上の要素がちょうどk個」成立するkを見つける方法
非負の整数のみを含むリスト nums が与えられます。この中から、「k 以上の値を持つ要素がちょうど k 個存在する」ような整数 k を見つけて返すことを考えます。条件を満たす k が存在しない場合は -1 を返します。たとえば、入力が nums = [6, 4, 0, 8, 2, 9] の場合を考えてみましょう。4 以上の値を持つ要素は [6, 4, 8, 9] のちょうど 4 個であるため、答えは 4 になります。解法の考え方この問題は、リストを降順にソートすることで効率的に解けます。降順ソート後のリストでは、インデックス i より前にある要素はすべて nums[i - 1] 以上の値を持