Definição
Alterado na versão 5.0.
$exprPermite 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, parciais ou esparsos não são usados.
Exemplos
Os exemplos nesta página usam dados do conjunto de dados de amostra sample_mflix. Para obter detalhes sobre como carregar esse conjunto de dados em sua implantação autogerenciada do MongoDB , consulte Carregar o conjunto de dados de amostra. Se você fez modificações nos bancos de dados de amostra, talvez seja necessário descartar e recriar os bancos de dados para executar os exemplos nesta página.
Comparar dois campos de um único documento
$expr pode conter expressões que comparam campos do mesmo documento.
The following operation uses $expr to find documents in the movies collection where the Rotten Tomatoes viewer rating exceeds the critic rating:
db.movies.find( { $expr: { $gt: [ "$tomatoes.viewer.rating", "$tomatoes.critic.rating" ] } }, { _id: 0, title: 1, "tomatoes.viewer.rating": 1, "tomatoes.critic.rating": 1 } ).sort( { "tomatoes.viewer.rating": -1 } ).limit( 3 )
[ { title: 'I Am Maria', tomatoes: { viewer: { rating: 5 } } }, { title: 'Kadin Hamlet', tomatoes: { viewer: { rating: 5 } } }, { title: 'The Seine Meets Paris', tomatoes: { viewer: { rating: 5 } } } ]
Use $expr com declarações condicionais
Some queries need to execute conditional logic when defining a query filter. The aggregation pipeline provides the $cond operator to express conditional statements. By using $expr with the $cond operator, you can specify a conditional filter for your query statement.
Assume you want to calculate a weighted score for movies so that highly-rated movies with few votes do not dominate the results:
If
imdb.votesis greater than or equal to 1000, the weighted score is the fullimdb.rating.If
imdb.votesis less than 1000, the weighted score is 0.5 of theimdb.rating.
You would like to know which movies in the movies collection have a weighted score greater than 9.
The following example uses $expr with $cond to calculate the weighted score based on imdb.votes and $gt to return documents whose calculated weighted score is greater than 9:
db.movies.find( { "imdb.rating": { $type: "number" }, "imdb.votes": { $type: "number" }, $expr: { $gt: [ { $cond: { if: { $gte: ["$imdb.votes", 1000] }, then: { $multiply: ["$imdb.rating", 1.0] }, else: { $multiply: ["$imdb.rating", 0.5] } } }, 9 ] } }, { _id: 0, title: 1, "imdb.rating": 1, "imdb.votes": 1 } ).sort( { title: 1 } ).limit(5)
The following table shows the weighted score for selected documents and whether the weighted score is greater than 9 (i.e. whether the document meets the query condition).
Documento | Weighted Score | > 9 |
|---|---|---|
| 9.3 |
|
| 9.2 |
|
| 8.9 |
|
| 9.5 |
|
| 4.55 |
|
The db.collection.find() operation returns 5 documents whose calculated weighted score is greater than 9:
[ { title: 'Band of Brothers', imdb: { rating: 9.6, votes: 183802 } }, { title: 'Baseball', imdb: { rating: 9.1, votes: 2460 } }, { title: 'Cosmos', imdb: { rating: 9.3, votes: 17174 } }, { title: 'Frozen Planet', imdb: { rating: 9.2, votes: 5903 } }, { title: 'Human Planet', imdb: { rating: 9.2, votes: 9057 } } ]
Even though $cond calculates a weighted score, that score is not reflected in the returned documents. Instead, the returned documents represent the matching documents in their original state.