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コレクションのインデックスを使用できます。 制限:

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

  • オペランドが配列である場合、またはオペランドの型が未定義である場合の比較にはインデックスは使用されません。

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

以下のドキュメントを持つ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を超えていたため、返されませんでした。

戻る

評価クエリ