정의
버전 5.0에서 변경됨
호환성
다음 환경에서 호스팅되는 배포에 $expr 사용할 수 있습니다.
MongoDB Atlas: 클라우드에서의 MongoDB 배포를 위한 완전 관리형 서비스
MongoDB Enterprise: MongoDB의 구독 기반 자체 관리 버전
MongoDB Community: MongoDB의 소스 사용 가능 무료 자체 관리 버전
구문
{ $expr: { <expression> } }
인수는 유효한 모든 표현식일 수 있습니다.
행동
$lookup 작업의 $expr
$lookup 하위 단계에 속해 있는 $match 단계에 $expr이 나타나는 경우 $expr은 $lookup 단계에서 정의된 let 변수를 참조할 수 있습니다. 예시는 다중 조인 조건 및 상관관계 하위 쿼리 사용을 참조하세요.
$expr 연산자에 배치된 $eq, $lt, $lte, $gt 및 $gte 비교 연산자는 $lookup 단계에서 참조된 from 컬렉션의 인덱스를 사용할 수 있습니다. 제한 사항:
인덱스는 필드와 상수 간의 비교에만 사용할 수 있으므로
let피연산자는 상수로 해결되어야 합니다.예를 들어
$a및 상수 값 간의 비교에는 인덱스를 사용할 수 있지만,$a및$b간의 비교에는 인덱스를 사용할 수 없습니다.let피연산자가 비어 있거나 누락된 값으로 확인되는 비교에는 인덱스가 사용되지 않습니다.다중 키 인덱스 는 사용되지 않습니다.
예시
단일 문서에서 두 필드 비교
$expr 동일한 문서의 필드를 비교하는 표현식이 포함될 수 있습니다.
이 문서로 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 }
조건문과 함께 $expr 사용
일부 쿼리에는 쿼리 필터를 정의할 때 조건부 논리를 실행하는 기능이 필요합니다. 집계 파이프라인은 조건문을 표현하는 $cond 연산자를 제공합니다. $cond 연산자와 함께 $expr을 사용하면 쿼리 문에 대한 조건 필터를 지정할 수 있습니다.
다음 문서로 샘플 supplies 컬렉션을 생성합니다.
db.supplies.insertMany( [ { _id : 1, item : "binder", qty : Int32("100"), price : Decimal128("12") }, { _id : 2, item : "notebook", qty : Int32("200"), price : Decimal128("8") }, { _id : 3, item : "pencil", qty : Int32("50"), price : Decimal128("6") }, { _id : 4, item : "eraser", qty : Int32("150"), price : Decimal128("3") }, { _id : 5, item : "legal pad", qty : Int32("42"), price : Decimal128("10") } ] )
다음 달에 예정된 판매에 대해 다음과 같이 가격을 할인하려고 한다고 가정합니다.
qty이(가) 100보다 크거나 같으면 할인된 가격은price의 0.5가 됩니다.qty이(가) 100보다 작은 경우 할인된 가격은price의 0.75가 됩니다.
할인을 적용하기 전에 supplies collection에서 할인된 가격이 미만인 품목이 무엇인지 알고 5 싶습니다.
다음 예에서는 $expr과 함께 $cond를 사용하여 qty 및 $lt를 기반으로 할인 가격을 계산하여 계산된 할인 가격이 Decimal128("5")보다 작은 문서를 반환합니다.
// Aggregation expression to calculate discounted price let discountedPrice = { $cond: { if: { $gte: ["$qty", 100] }, then: { $multiply: ["$price", Decimal128("0.50")] }, else: { $multiply: ["$price", Decimal128("0.75")] } } }; // Query the supplies collection using the aggregation expression db.supplies.find( { $expr: { $lt:[ discountedPrice, Decimal128("5") ] } });
다음 표에는 각 문서의 할인가와 할인된 가격이 Decimal128("5") 미만인지 여부가 나와 있습니다 (즉, 문서가 쿼리 조건을 충족하는지 여부).
문서 | 할인 가격 | < Decimal128("5") |
|---|---|---|
{"_id": 1, "item": "binder", "qty": 100, "price": Decimal128("12") } | Decimal128("6.00") |
|
{"_id": 2, "item": "notebook", "qty": 200, "price": Decimal128("8") } | Decimal128("4.00") |
|
{"_id": 3, "item": "pencil", "qty": 50, "price": Decimal128("6") } | Decimal128("4.50") |
|
{"_id": 4, "item": "eraser", "qty": 150, "price": Decimal128("3") } | Decimal128("1.50") |
|
{"_id": 5, "item": "legal pad", "qty": 42, "price": Decimal128("10") } | Decimal128("7.50") |
|
db.collection.find() 작업은 계산된 할인 가격이 Decimal128("5")미만인 문서를 반환합니다.
{ _id : 2, item : "notebook", qty : 200 , price : Decimal128("8") } { _id : 3, item : "pencil", qty : 50 , price : Decimal128("6") } { _id : 4, item : "eraser", qty : 150 , price : Decimal128("3") }
$cond에서 유효 할인 가격을 계산하더라도 반품된 문서에는 해당 가격이 반영되지 않습니다. 대신 반환된 문서는 원래 상태의 일치하는 문서를 나타냅니다. 할인된 가격이 5 보다 컸기 때문에 찾기 작업을 수행해도 binder 또는 legal pad 문서가 반환되지 않았습니다.