【MongoDB】フィールドが存在しない・null・falseのドキュメントを$in演算子で一括取得する方法
MongoDBで「存在しない・null・false」のフィールドを持つドキュメントを検索するには?
MongoDBでは、$in演算子を使うことで、「特定のフィールドが存在しない」「値がnullである」「値がfalseである」という3つの条件を、たった1つのクエリでまとめて判定できます。
この記事では、実際にサンプルデータを作成しながら、具体的なクエリの書き方と実行結果をわかりやすく解説します。
サンプルコレクションの作成
まず、動作確認用のコレクションを作成し、複数のドキュメントを挿入します。あえて「フィールド自体がないドキュメント」「nullが設定されたドキュメント」「falseが設定されたドキュメント」を混ぜて登録するのがポイントです。
> db.selectMongoDBDocumentsWithSomeCondition.insertOne({"StudentId":1,"StudentName":"Larry"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c9010215705caea966c557f")
}
> db.selectMongoDBDocumentsWithSomeCondition.insertOne({"StudentId":2,"StudentName":"Mike","hasAgeGreaterThanOrEqualTo18":true});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c90106a5705caea966c5580")
}
> db.selectMongoDBDocumentsWithSomeCondition.insertOne({"StudentId":3,"StudentName":"Carol","hasAgeGreaterThanOrEqualTo18":false});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c9010795705caea966c5581")
}
> db.selectMongoDBDocumentsWithSomeCondition.insertOne({"StudentId":4,"StudentName":"Sam","hasAgeGreaterThanOrEqualTo18":null});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c9010865705caea966c5582")
}
> db.selectMongoDBDocumentsWithSomeCondition.insertOne({"StudentId":5,"StudentName":"David","hasAgeGreaterThanOrEqualTo18":false});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c9010945705caea966c5583")
}
> db.selectMongoDBDocumentsWithSomeCondition.insertOne({"StudentId":6,"StudentName":"Chris","hasAgeGreaterThanOrEqualTo18":null});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c9010a45705caea966c5584")
}
> db.selectMongoDBDocumentsWithSomeCondition.insertOne({"StudentId":7,"StudentName":"Robert","hasAgeGreaterThanOrEqualTo18":true});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c9010b05705caea966c5585")
}
登録された全ドキュメントの確認
find()メソッドを実行して、コレクション内のすべてのドキュメントを表示してみましょう。
> db.selectMongoDBDocumentsWithSomeCondition.find().pretty();
実行結果は以下の通りです。7件のうち、StudentIdが2と7だけが true になっていることが確認できます。
{
"_id" : ObjectId("5c9010215705caea966c557f"),
"StudentId" : 1,
"StudentName" : "Larry"
}
{
"_id" : ObjectId("5c90106a5705caea966c5580"),
"StudentId" : 2,
"StudentName" : "Mike",
"hasAgeGreaterThanOrEqualTo18" : true
}
{
"_id" : ObjectId("5c9010795705caea966c5581"),
"StudentId" : 3,
"StudentName" : "Carol",
"hasAgeGreaterThanOrEqualTo18" : false
}
{
"_id" : ObjectId("5c9010865705caea966c5582"),
"StudentId" : 4,
"StudentName" : "Sam",
"hasAgeGreaterThanOrEqualTo18" : null
}
{
"_id" : ObjectId("5c9010945705caea966c5583"),
"StudentId" : 5,
"StudentName" : "David",
"hasAgeGreaterThanOrEqualTo18" : false
}
{
"_id" : ObjectId("5c9010a45705caea966c5584"),
"StudentId" : 6,
"StudentName" : "Chris",
"hasAgeGreaterThanOrEqualTo18" : null
}
{
"_id" : ObjectId("5c9010b05705caea966c5585"),
"StudentId" : 7,
"StudentName" : "Robert",
"hasAgeGreaterThanOrEqualTo18" : true
}
$in演算子で3つの条件を一度に指定する
ここからが本題です。「フィールドが存在しない」「null」「false」のいずれかに該当するドキュメントを抽出するには、次のように $in 演算子に [false, null] を渡します。
> db.selectMongoDBDocumentsWithSomeCondition.find({ "hasAgeGreaterThanOrEqualTo18": {$in: [false,null]}}).pretty();
実行結果は以下の通りです。true が設定されていたStudentId 2(Mike)と 7(Robert)以外の、5件のドキュメントが取得できました。
{
"_id" : ObjectId("5c9010215705caea966c557f"),
"StudentId" : 1,
"StudentName" : "Larry"
}
{
"_id" : ObjectId("5c9010795705caea966c5581"),
"StudentId" : 3,
"StudentName" : "Carol",
"hasAgeGreaterThanOrEqualTo18" : false
}
{
"_id" : ObjectId("5c9010865705caea966c5582"),
"StudentId" : 4,
"StudentName" : "Sam",
"hasAgeGreaterThanOrEqualTo18" : null
}
{
"_id" : ObjectId("5c9010945705caea966c5583"),
"StudentId" : 5,
"StudentName" : "David",
"hasAgeGreaterThanOrEqualTo18" : false
}
{
"_id" : ObjectId("5c9010a45705caea966c5584"),
"StudentId" : 6,
"StudentName" : "Chris",
"hasAgeGreaterThanOrEqualTo18" : null
}
なぜこれで「フィールドが存在しない」ケースも取れるのか?
ポイントは、MongoDBでは null との比較において、該当フィールドが存在しないドキュメントもマッチ対象になるという仕様です。
そのため、{$in: [false, null]} という条件だけで、以下の3パターンをすべてカバーできます。
- フィールド自体が存在しないドキュメント(例:StudentId 1 の Larry)
- フィールドの値が明示的に null のドキュメント(例:StudentId 4 の Sam)
- フィールドの値が false のドキュメント(例:StudentId 3 の Carol)
逆に言えば、値が true のドキュメントのみを除外したい場面で、この書き方は非常に便利です。$or を使って複数条件を組み合わせるよりもシンプルに記述できるため、実務でもよく使われるテクニックです。
-
MySQLで特定の値が存在しないレコードを抽出する方法(NOT IN句の使い方)
MySQLでテーブルから「特定の値を含まない」レコードだけを取得したい場合は、NOT IN() 句を使用します。この記事では、実際にサンプルテーブルを作成しながら、NOT IN句の基本的な使い方を解説します。サンプルテーブルの作成まず、学生情報を格納するためのテーブルを作成しましょう。StudentId を主キー(AUTO_INCREMENT)とし、StudentName カラムを持つシンプルなテーブルです。mysql> create table DemoTable1991 ( StudentId int NOT NULL AUTO_INCREMENT PRIMARY KEY,
-
Windowsでドメイン参加時に「指定されたドメインが存在しないか、接続できませんでした」と表示される場合の対処法
Windowsパソコンを既存のActive Directoryドメインに参加させようとした際、「指定されたドメインが存在しないか、接続できませんでした(The specified domain either does not exist or could not be contacted)」というエラーメッセージが表示されることがあります。このエラーは、ユーザー名とパスワードを入力した直後に発生するのが特徴です。 このエラーの最も一般的な原因は、クライアント側ワークステーションのDNS設定が不正であることです。Active Directoryが正常に動作するためには、ルーターのアドレスではな