Definição
Alterado na versão 5.0.
- $expr
- Permite o uso de expressões dentro de um predicado de query. 
Compatibilidade
Você pode utilizar o $expr para implantações hospedadas nos seguintes ambientes:
- MongoDB Atlas: o serviço totalmente gerenciado para implantações do MongoDB na nuvem 
- MongoDB Enterprise: a versão autogerenciada e baseada em assinatura do MongoDB 
- MongoDB Community: uma versão com código disponível, de uso gratuito e autogerenciada do MongoDB 
Sintaxe
{ $expr: { <expression> } } 
O argumento pode ser qualquer expressão válida.
Comportamento
$expr em operações de $lookup
Quando $expr aparece em um estágio $match que faz parte de um subpipeline $lookup, $expr pode se referir a variáveis let definidas pelo estágio $lookup. Para obter um exemplo, consulte Usar várias condições de junção e uma subquery correlacionada.
Os operadores de comparação $eq, $lt, $lte, $gt e $gte colocados em um operador $expr podem utilizar um índice na coleção from referenciada em um estágio $lookup. Limitações:
- Os índices só podem ser usados para comparações entre campos e constantes, portanto, o operando - letdeve ser resolvido para uma constante.- Por exemplo, uma comparação entre - $ae um valor constante pode usar um índice, mas uma comparação entre- $ae- $bnão pode.
- Os índices não são usados para comparações onde o operando - letresolve para um valor vazio ou ausente.
- Índices multichave não são usados. 
Exemplos
Comparar dois campos de um único documento
$expr pode conter expressões que comparam campos do mesmo documento.
Crie uma coleção monthlyBudget com estes documentos:
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 } ] ) 
A operação a seguir usa $expr para localizar documentos em que o valor spent excede budget:
db.monthlyBudget.find( { $expr: { $gt: [ "$spent" , "$budget" ] } } ) 
Saída:
{ _id : 1, category : "food", budget : 400, spent : 450 } { _id : 2, category : "drinks", budget : 100, spent : 150 } { _id : 5, category : "travel", budget : 200, spent : 650 } 
Use $expr com declarações condicionais
Algumas queries exigem a capacidade de executar lógica condicional ao definir um filtro de query. O pipeline de agregação fornece o operador $cond para expressar declarações condicionais. Ao usar $expr com o operador $cond, você pode especificar um filtro condicional para sua declaração de consulta.
Criar uma coleção supplies de amostra com os seguintes documentos:
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") } ] ) 
Suponha que, para uma futura venda no próximo mês, você queira descontar os preços de forma que:
- Se - qtyfor maior ou igual a 100, o preço com desconto seja 0,5 do- price.
- Se - qtyfor inferior a 100, o preço com desconto seja 0,75 do- price.
Antes de aplicar os descontos, você gostaria de saber quais itens da collection supplies têm um preço com desconto inferior a 5.
O exemplo a seguir usa $expr com $cond para calcular o preço com desconto com base em qty e $lt para retornar documentos cujo preço com desconto calculado é menor que 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") ] } }); 
A tabela a seguir mostra o preço com desconto para cada documento e se o preço com desconto é inferior a Decimal128("5") (ou seja, se o documento atende à condição de query).
| Documento | Preço com desconto | < 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") | 
 | 
A operação db.collection.find() retorna os documentos cujo preço com desconto calculado é menor que 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") } 
Embora $cond calcule um preço com desconto efetivo, esse preço não é refletido nos documentos retornados. Em vez disso, os documentos retornados representam os documentos correspondentes em seu estado original. A operação de busca não retornou os documentos binder ou legal pad, pois o preço com desconto era maior que 5.