$let(集計)
定義
$let
指定された式で使用する変数をバインドし、式の結果を返します。
$let
式の構文は次のとおりです。{ $let: { vars: { <var1>: <expression>, ... }, in: <expression> } } フィールド仕様vars
in
式でアクセス可能な変数の割り当てブロックです。変数を割り当てるには、変数名に文字列を指定し、値に有効な式を割り当てます。変数の割り当ては、
in
式の外部では意味がなく、vars
ブロック自体でも意味を持ちません。in
評価する式です。集計式内の変数にアクセスするには、変数名の前に二重ドル記号(
$$
)を付けて引用符で囲みます。式の詳細については、「式演算子」を参照してください。集計パイプラインでの変数の使用については、「集計式の変数」を参照してください。
動作
$let
は、システム変数を含む、式ブロック外で定義された変数にアクセスできます。
vars
ブロック内の外部定義された変数の値を変更すると、新しい値は in
式でのみ有効になります。in
式の外部では、変数は以前の値を保持します。
vars
割り当てブロックでは、割り当ての順序は重要ではなく、変数割り当ては in
式の中でのみ意味を持ちます。そのため、vars
割り当てブロック内で変数の値にアクセスすると、同じ vars
ブロック内ではなく vars
ブロックの外部で定義された変数の値が参照されます。
たとえば、次の$let
式について考えてみます。
{ $let: { vars: { low: 1, high: "$$low" }, in: { $gt: [ "$$low", "$$high" ] } } }
vars
割り当てブロックでは、 "$$low"
は、同じvars
ブロックで定義された変数ではなく、外部定義された変数low
の値を参照します。 この$let
式ブロックの外部でlow
が定義されていない場合、式は無効になります。
例
sales
コレクションには、次のドキュメントがあります。
{ _id: 1, price: 10, tax: 0.50, applyDiscount: true } { _id: 2, price: 10, tax: 0.25, applyDiscount: false }
次の集計では、$project
パイプライン ステージで $let
を使用して、各ドキュメントの finalTotal
を計算して返します。
db.sales.aggregate( [ { $project: { finalTotal: { $let: { vars: { total: { $add: [ '$price', '$tax' ] }, discounted: { $cond: { if: '$applyDiscount', then: 0.9, else: 1 } } }, in: { $multiply: [ "$$total", "$$discounted" ] } } } } } ] )
この集計は、次の結果を返します。
{ "_id" : 1, "finalTotal" : 9.450000000000001 } { "_id" : 2, "finalTotal" : 10.25 }