Menu Docs

Página inicial do DocsDesenvolver aplicaçõesManual do MongoDB

$expr

Nesta página

  • Definição
  • Compatibilidade
  • Sintaxe
  • Comportamento
  • Exemplos

Alterado na versão 5.0.

$expr

Permite o uso de expressões de aggregation dentro da linguagem de query.

Você pode utilizar o $expr para implantações hospedadas nos seguintes ambientes:

  • MongoDB Atlas: o serviço totalmente gerenciado para implantações MongoDB na nuvem

$expr tem a seguinte sintaxe:

{ $expr: { <expression> } }

Os parâmetros podem ser qualquer expressão de aggregation válida. Para obter mais informações, consulte Operadores de expressão.

$expr pode criar expressões de query que comparam campos do mesmo documento em um estágio $match .

Se o estágio $match fizer parte de um estágio $lookup , $expr poderá comparar campos usando variáveis let . Consulte Realizar várias uniões e uma subquery correlacionada com $lookup para obter um exemplo.

Os operadores de comparação $eq, $lt, $lte, $gt e $gte colocados em um operador $expr podem utilizar um índice na collection from referenciada em um estágio $lookup . Limitações:

  • Índices multichave não são usados.

  • Os índices não são usados para comparações onde o operando é um array ou o tipo de operando é indefinido.

  • Os índices não são usados para comparações com mais de um operando de caminho do campo.

Considere uma collection monthlyBudget com os seguintes 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 ] } } )

A operação retorna os seguintes resultados:

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

Algumas queries exigem a capacidade de executar lógica condicional ao definir um filtro de query. O aggregation pipeline fornece ao operador $cond para expressar instruções condicionais. Usando $expr com o operador $cond , você pode especificar um filtro condicional para sua declaração de query.

Criar uma coleção supplies de amostra com os seguintes documentos:

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") }
] )

Suponha que, para uma futura venda no próximo mês, você queira descontar os preços de forma que:

  • Se qty for maior ou igual a 100, o preço com desconto seja 0,5 do price.

  • Se qty for 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 de desconto calculado é menor que 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") ] } });

A tabela a seguir mostra o preço com desconto para cada documento e se o preço com desconto é inferior a NumberDecimal("5") (ou seja, se o documento atende à condição de query).

Documento
Preço com desconto
< 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

A operação db.collection.find() retorna os documentos cujo preço com desconto calculado é menor que 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") }

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.

← Operadores de query de avaliação