Docs Menu
Docs Home
/
MongoDBマニュアル
/ / / /

$expr

項目一覧

  • 定義
  • 互換性
  • 構文
  • 動作

バージョン 5.0 での変更

$expr

クエリ言語の中で 集計式を使用できます。

次の環境でホストされる配置には $expr を使用できます。

  • MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです

  • MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン

  • MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン

$expr の構文は次のとおりです。

{ $expr: { <expression> } }

引数には、あらゆる有効な集計式となる可能性があります。 詳細については、「式 」を参照してください。

$exprは、 $matchステージの同じドキュメントのフィールドを比較するクエリ式を作成できます。

$matchステージが$lookupステージの一部である場合、 $exprlet変数を使用してフィールドを比較できます。 例については$lookupを使用して複数の結合と相関サブクエリを実行する 」を参照してください。

$expr演算子に配置されている$eq$lt$lte$gt 、および$gte比較演算子は、 $lookupステージで参照されるfromコレクションのインデックスを使用できます。 制限:

  • インデックスはフィールドと定数の比較にのみ使用できるため、let オペランドは定数に変換する必要があります。

    たとえば、$a と定数値の比較にはインデックスを使用できますが、$a$b の比較には使用できません。

  • let オペランドが空の値または欠損値に変換される場合の比較には、インデックスは使用されません。

  • マルチキーインデックスは使用されません

以下のドキュメントを持つmonthlyBudgetコレクションを考えてみましょう。

db.monthlyBudget.insertMany( [
{ _id : 1, category : "food", budget : 400, spent : 450 },
{ _id : 2, category : "drinks", budget : 100, spent : 150 },
{ _id : 3, category : "clothes", budget : 100, spent : 50 },
{ _id : 4, category : "misc", budget : 500, spent : 300 },
{ _id : 5, category : "travel", budget : 200, spent : 650 }
] )

次の操作では、 $exprを使用して、 spentの量がbudgetを超えるドキュメントを検索します。

db.monthlyBudget.find( { $expr: { $gt: [ $spent , $budget ] } } )

この操作は次の結果を返します。

{ _id : 1, category : "food", budget : 400, spent : 450 }
{ _id : 2, category : "drinks", budget : 100, spent : 150 }
{ _id : 5, category : "travel", budget : 200, spent : 650 }

一部のクエリでは、クエリフィルターを定義するときに条件ロジックを実行する能力が必要です。 集計パイプラインには、条件ステートメントを$cond Expressするための 演算子が用意されています。$expr$cond演算子とともに使用することで、クエリ ステートメントに条件付きフィルターを指定できます。

次のドキュメントを使用してサンプルsupplies コレクションを作成します。

db.supplies.insertMany( [
{ _id : 1, item : "binder", qty : NumberInt("100"), price : NumberDecimal("12") },
{ _id : 2, item : "notebook", qty : NumberInt("200"), price : NumberDecimal("8") },
{ _id : 3, item : "pencil", qty : NumberInt("50"), price : NumberDecimal("6") },
{ _id : 4, item : "eraser", qty : NumberInt("150"), price : NumberDecimal("3") },
{ _id : 5, item : "legal pad", qty : NumberInt("42"), price : NumberDecimal("10") }
] )

来月予定されているセールで、次のように価格を割引したいとします。

  • qtyが 100 以上の場合、割引価格はpriceの 0.5 倍になります。

  • qtyが 100 未満の場合、割引価格はpriceの 0.75 倍になります。

割引を適用する前に、 supplies コレクション内のどのアイテムの割引価格が 5 未満であるかを確認する必要があります。

次の例では、 $expr$condを使用して、 qty$ltに基づいて割引価格を計算し、計算された割引価格がNumberDecimal("5")より小さいドキュメントを返します。

// Aggregation expression to calculate discounted price
let discountedPrice = {
$cond: {
if: { $gte: ["$qty", 100] },
then: { $multiply: ["$price", NumberDecimal("0.50")] },
else: { $multiply: ["$price", NumberDecimal("0.75")] }
}
};
// Query the supplies collection using the aggregation expression
db.supplies.find( { $expr: { $lt:[ discountedPrice, NumberDecimal("5") ] } });

次の表は、各文書の割引価格と、割引価格がNumberDecimal("5")未満であるかどうかを示しています(つまり、 ドキュメントがクエリ条件を満たしているかどうか)。

ドキュメント
Discounted Price
< NumberDecimal("5")
{"_id": 1, "item": "binder", "qty": 100, "price": NumberDecimal("12") }
NumberDecimal("6.00")
false
{"_id": 2, "item": "notebook", "qty": 200, "price": NumberDecimal("8") }
NumberDecimal("4.00")
true
{"_id": 3, "item": "pencil", "qty": 50, "price": NumberDecimal("6") }
NumberDecimal("4.50")
true
{"_id": 4, "item": "eraser", "qty": 150, "price": NumberDecimal("3") }
NumberDecimal("1.50")
true
{"_id": 5, "item": "legal pad", "qty": 42, "price": NumberDecimal("10") }
NumberDecimal("7.50")
false

db.collection.find()操作は、計算された割引価格がNumberDecimal("5")未満のドキュメントを返します。

{ _id : 2, item : "notebook", qty : 200 , price : NumberDecimal("8") }
{ _id : 3, item : "pencil", qty : 50 , price : NumberDecimal("6") }
{ _id : 4, item : "eraser", qty : 150 , price : NumberDecimal("3") }

$condでは有効な割引価格が計算されますが、その価格は返されるドキュメントには反映されません。その代わり、返されるドキュメントは、一致したドキュメントをオリジナルの状態で表現します。検索操作では、 binder ドキュメントまたは legal pad ドキュメントは、割引価格が 5を超えていたため、返されませんでした。

戻る

評価クエリ