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

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演算子も利用可能。
  1. MongoDBで複数フィールドの存在を確認するクエリの書き方($existsと$andの活用)

    MongoDBで複数のフィールドの存在を確認する方法MongoDBでは、ドキュメント内に特定の複数のフィールドがすべて存在するかどうかを確認したいケースがよくあります。そのような場合には、$exists 演算子と $and 演算子を組み合わせて使用します。この記事では、実際にコレクションを作成しながら、複数フィールドの存在をチェックするクエリの書き方を具体的に解説します。1. サンプルコレクションとドキュメントの作成まず、insertOne() メソッドを使って、コレクション demo475 にドキュメントを挿入していきます。> db.demo475.insertOne({Student

  2. MongoDBのfind()で特定のフィールドを除外して取得する方法

    MongoDBのfind()クエリで不要なフィールドを除外する基本構文MongoDBでは、find()メソッドの第2引数に射影(プロジェクション)を指定することで、結果から表示したくないフィールドを除外できます。除外したいフィールドには 0 を設定します。以下が基本の構文です。ここでは「yourFieldName1」と「yourFieldName2」という2つのフィールドを除外しています。db.yourCollectionName.find(yourQuery, {yourFieldName1: 0, yourFieldName2: 0});サンプルコレクションの作成実際に動作を確認するため、