MongoDB
 Computer >> コンピューター >  >> プログラミング >> MongoDB

MongoDBで配列フィールドの全要素がスーパーセット(許容リスト)に含まれているか判定する方法

MongoDBにおいて、あるフィールド(配列)のすべての要素が特定のスーパーセット(許容リスト)に含まれているかどうかを確認したい場合があります。例えば「リスト内の名前がすべてホワイトリストに登録されているか」をチェックするようなケースです。

このような判定には、find()メソッドに対して$elemMatch演算子を使用します。$elemMatchは、指定されたすべてのクエリ条件に一致する要素を少なくとも1つ含む配列フィールドを持つドキュメントにマッチします。さらに、これを$not$ninと組み合わせることで、「スーパーセットに含まれていない要素を1つも持たない(=すべての要素がスーパーセットに含まれる)」ドキュメントを抽出できます。

サンプルコレクションの作成

まず、ドキュメントを含むコレクションを作成します。ここではdemo624というコレクションに、名前のリストを持つドキュメントを挿入していきます。

> db.demo624.insertOne({"ListOfName":["John","Chris","David","Bob"]});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5e9ab3ff6c954c74be91e6a5")
}
> db.demo624.insertOne({"ListOfName":["John","Chris"]});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5e9ab4026c954c74be91e6a6")
}
> db.demo624.insertOne({"ListOfName":["John","Chris","Carol"]});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5e9ab4076c954c74be91e6a7")
}
> db.demo624.insertOne({"ListOfName":["John","Chris","Bob"]});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5e9ab40e6c954c74be91e6a8")
}
> db.demo624.insertOne({"ListOfName":["John","Chris","Mike","Robert"]});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5e9ab4186c954c74be91e6a9")
}

コレクション内の全ドキュメントを表示する

find()メソッドを使って、コレクション内のすべてのドキュメントを表示してみましょう。

> db.demo624.find();

このクエリを実行すると、以下の出力が得られます。

{ "_id" : ObjectId("5e9ab3ff6c954c74be91e6a5"), "ListOfName" : [ "John", "Chris", "David", "Bob" ] }
{ "_id" : ObjectId("5e9ab4026c954c74be91e6a6"), "ListOfName" : [ "John", "Chris" ] }
{ "_id" : ObjectId("5e9ab4076c954c74be91e6a7"), "ListOfName" : [ "John", "Chris", "Carol" ] }
{ "_id" : ObjectId("5e9ab40e6c954c74be91e6a8"), "ListOfName" : [ "John", "Chris", "Bob" ] }
{ "_id" : ObjectId("5e9ab4186c954c74be91e6a9"), "ListOfName" : [ "John", "Chris", "Mike", "Robert" ] }

スーパーセットへの包含を確認するクエリ

それでは、フィールドのすべての要素がスーパーセットに含まれているかどうかを判定するクエリを見ていきましょう。ここではスーパーセットとして["John", "Chris", "David", "Bob"]を指定し、このリスト外の名前を含まないドキュメントのみを抽出します。

> db.demo624.find({"ListOfName":{$not:{$elemMatch:{$nin:["John", "Chris", "David", "Bob"]}}}});

このクエリを実行すると、以下の出力が得られます。

{ "_id" : ObjectId("5e9ab3ff6c954c74be91e6a5"), "ListOfName" : [ "John", "Chris", "David", "Bob" ] }
{ "_id" : ObjectId("5e9ab4026c954c74be91e6a6"), "ListOfName" : [ "John", "Chris" ] }
{ "_id" : ObjectId("5e9ab40e6c954c74be91e6a8"), "ListOfName" : [ "John", "Chris", "Bob" ] }

結果の解説

出力結果からわかるように、["John", "Chris", "David", "Bob"]以外の名前(例えば「Carol」「Mike」「Robert」など)を含むドキュメントは除外され、リスト内のすべての要素がスーパーセットに含まれる3件のドキュメントだけが返されました。

ポイントとなるのはクエリの構造です。$ninによって「スーパーセットに含まれない要素」を検出し、そのような要素を1つでも持つドキュメントを$elemMatchがマッチさせ、最終的に$notでそのマッチを反転させています。つまり「スーパーセット外の要素を一切含まない=全要素がスーパーセットに含まれる」という条件を実現しているのです。

このテクニックは、タグの妥当性チェック、権限リストの検証、カテゴリの制約チェックなど、配列フィールドの内容が許容範囲に収まっていることを保証したいさまざまなシーンで活用できます。

  1. MongoDBコレクション内のすべてのドキュメントに新しいフィールドを追加する方法

    MongoDBコレクション内のすべてのドキュメントに新しいフィールドを追加する方法MongoDBで既存のドキュメントに新しいフィールドを追加するには、集計パイプラインの$addFieldsステージを使用します。まずは、サンプルとなるコレクションとドキュメントを作成してみましょう。サンプルコレクションの作成insertOne()メソッドを使用して、ドキュメントを1件ずつ挿入します。> db.demo712.insertOne({Name:John}); { acknowledged : true, insertedId : ObjectId(5ea85f675d33e20ed1

  2. MongoDB 4でドキュメントをソートし、特定の1つのフィールドだけを表示する方法

    MongoDB 4でドキュメントを並べ替えるには、sort()メソッドを使用します。さらに、ソートした特定の1つのフィールドのみを表示したい場合は、プロジェクション(射影)を組み合わせて、表示したいフィールドに「1」を設定します。この記事では、実際のコード例を使って手順を順番に解説していきます。1. サンプルコレクションの作成まず、insertOne()メソッドを使って、テスト用のコレクション「demo611」にドキュメントを登録します。> db.demo611.insertOne({Name:Chris}); { acknowledged : true, insertedI