MongoDBで2つのフィールドを比較するクエリ条件の書き方
MongoDBで2つのフィールドを比較するには?
MongoDBでは、通常のクエリ条件は同一フィールド内の値と比較しますが、同じドキュメント内の異なる2つのフィールド同士を比較したい場合があります。そのようなときは、$where演算子とJavaScript関数を組み合わせることで実現できます。
基本構文
2つのフィールドを比較して条件検索を行う場合、以下の構文を使用します。
db.yourCollectionName.find( { $where: function() { return this.yourFirstFieldName < this.yourSecondFieldName } } ).pretty();この構文では、this.フィールド名で各ドキュメントの値にアクセスし、関数がtrueを返したドキュメントだけが結果として取得されます。
サンプルコレクションの作成
実際に動作を確認するため、ドキュメントを含むコレクションを作成しましょう。ここでは、学生ごとの数学と物理の点数を格納するコレクション「comparingTwoFieldsDemo」を作成します。
> db.comparingTwoFieldsDemo.insertOne({"StudentName":"John","StudentAge":21,"StudentMathMarks":99,"StudentPhysicsMarks":98});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c8ac09e6cea1f28b7aa0807")
}
> db.comparingTwoFieldsDemo.insertOne({"StudentName":"Carol","StudentAge":22,"StudentMathMarks":79,"StudentPhysicsMarks":89});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c8ac0b46cea1f28b7aa0808")
}
> db.comparingTwoFieldsDemo.insertOne({"StudentName":"David","StudentAge":24,"StudentMathMarks":39,"StudentPhysicsMarks":45});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c8ac0c96cea1f28b7aa0809")
}
> db.comparingTwoFieldsDemo.insertOne({"StudentName":"Bob","StudentAge":23,"StudentMathMarks":87,"StudentPhysicsMarks":78});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c8ac0e06cea1f28b7aa080a")
}登録済みドキュメントの確認
find()メソッドを使って、コレクション内のすべてのドキュメントを表示してみましょう。
> db.comparingTwoFieldsDemo.find().pretty();
実行結果は以下の通りです。
{
"_id" : ObjectId("5c8ac09e6cea1f28b7aa0807"),
"StudentName" : "John",
"StudentAge" : 21,
"StudentMathMarks" : 99,
"StudentPhysicsMarks" : 98
}
{
"_id" : ObjectId("5c8ac0b46cea1f28b7aa0808"),
"StudentName" : "Carol",
"StudentAge" : 22,
"StudentMathMarks" : 79,
"StudentPhysicsMarks" : 89
}
{
"_id" : ObjectId("5c8ac0c96cea1f28b7aa0809"),
"StudentName" : "David",
"StudentAge" : 24,
"StudentMathMarks" : 39,
"StudentPhysicsMarks" : 45
}
{
"_id" : ObjectId("5c8ac0e06cea1f28b7aa080a"),
"StudentName" : "Bob",
"StudentAge" : 23,
"StudentMathMarks" : 87,
"StudentPhysicsMarks" : 78
}数学の点数が物理の点数より低い学生を抽出する
それでは、「数学(StudentMathMarks)の点数が物理(StudentPhysicsMarks)の点数より低い」ドキュメントを取得するクエリを実行してみましょう。
> db.comparingTwoFieldsDemo.find( { $where: function() { return this.StudentMathMarks < this.StudentPhysicsMarks } } ).pretty();実行結果は以下の通りです。
{
"_id" : ObjectId("5c8ac0b46cea1f28b7aa0808"),
"StudentName" : "Carol",
"StudentAge" : 22,
"StudentMathMarks" : 79,
"StudentPhysicsMarks" : 89
}
{
"_id" : ObjectId("5c8ac0c96cea1f28b7aa0809"),
"StudentName" : "David",
"StudentAge" : 24,
"StudentMathMarks" : 39,
"StudentPhysicsMarks" : 45
}結果を見ると、Carolさん(数学79点 < 物理89点)とDavidさん(数学39点 < 物理45点)の2件のみが取得されています。Johnさん(99点 vs 98点)とBobさん(87点 vs 78点)は数学の点数が物理より高いため、除外されました。
補足:$expr演算子という選択肢
MongoDB 3.6以降では、$expr演算子を使うことでもフィールド間の比較が可能です。$exprは集計式(aggregation expression)をクエリ内で利用できる仕組みで、$whereよりもパフォーマンス面で有利なケースが多く、インデックスも活用できます。
> db.comparingTwoFieldsDemo.find(
... { $expr: { $lt: ["$StudentMathMarks", "$StudentPhysicsMarks"] } }
... ).pretty();新しいバージョンのMongoDBを使用している場合は、可読性と性能の観点から$exprの利用を検討するとよいでしょう。
まとめ
- 2つのフィールドを比較するには、
$where演算子にJavaScript関数を渡す。 - 関数内では
this.フィールド名でドキュメントの値にアクセスする。 - 条件に一致(trueを返す)したドキュメントのみが取得される。
- MongoDB 3.6以降では、より効率的な
$expr演算子も利用可能。
-
MongoDBで複数フィールドの存在を確認するクエリの書き方($existsと$andの活用)
MongoDBで複数のフィールドの存在を確認する方法MongoDBでは、ドキュメント内に特定の複数のフィールドがすべて存在するかどうかを確認したいケースがよくあります。そのような場合には、$exists 演算子と $and 演算子を組み合わせて使用します。この記事では、実際にコレクションを作成しながら、複数フィールドの存在をチェックするクエリの書き方を具体的に解説します。1. サンプルコレクションとドキュメントの作成まず、insertOne() メソッドを使って、コレクション demo475 にドキュメントを挿入していきます。> db.demo475.insertOne({Student
-
MongoDBのfind()で特定のフィールドを除外して取得する方法
MongoDBのfind()クエリで不要なフィールドを除外する基本構文MongoDBでは、find()メソッドの第2引数に射影(プロジェクション)を指定することで、結果から表示したくないフィールドを除外できます。除外したいフィールドには 0 を設定します。以下が基本の構文です。ここでは「yourFieldName1」と「yourFieldName2」という2つのフィールドを除外しています。db.yourCollectionName.find(yourQuery, {yourFieldName1: 0, yourFieldName2: 0});サンプルコレクションの作成実際に動作を確認するため、