Menu Docs
Página inicial do Docs
/
Manual 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 dentro de um predicado de query.

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

{ $expr: { <expression> } }

O argumento pode ser qualquer expressão válida.

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 let deve ser resolvido para uma constante.

    Por exemplo, uma comparação entre $a e um valor constante pode usar um índice, mas uma comparação entre $a e $b não pode.

  • Os índices não são usados para comparações onde o operando let resolve para um valor vazio ou ausente.

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

$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 }

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 : 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 com 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.

Voltar

Consulta de avaliação