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.
A operação a seguir usa $expr para encontrar documentos na coleção movies em que a classificação do visualizador do Rotten Tomatoes excede a classificação do crítico:
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
Algumas queries precisam executar lógica condicional ao definir um filtro de query. O pipeline de agregação fornece o operador $cond para Express declarações condicionais. Usando $expr com o operador $cond, você pode especificar um filtro condicional para sua declaração de query.
Suponha que você queira calcular uma pontuação ponderada para filmes de forma que os filmes bem avaliados com poucos votos não dominem os resultados:
Se
imdb.votesfor maior ou igual a 1000, a pontuação ponderada é oimdb.ratingcompleto.Se
imdb.votesfor inferior a 1000, a pontuação ponderada é 0.5 doimdb.rating.
Você gostaria de saber quais filmes da coleção movies têm uma pontuação ponderada maior que 9.
O exemplo a seguir usa $expr com $cond para calcular a pontuação ponderada com base em imdb.votes e $gt para retornar documentos cuja pontuação ponderada calculada é maior que 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)
A tabela a seguir mostra a pontuação ponderada para documentos selecionados e se a pontuação ponderada é maior que 9 (ou seja, se o documento atende à condição de query).
Documento | Pontuação Ponderada | > 9 |
|---|---|---|
| 9.3 |
|
| 9.2 |
|
| 8.9 |
|
| 9.5 |
|
| 4.55 |
|
A operação db.collection.find() retorna 5 documentos cuja pontuação ponderada calculada é maior que 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 } } ]
Embora $cond calcule uma pontuação ponderada, essa pontuação não é refletida nos documentos retornados. Em vez disso, os documentos retornados representam os documentos correspondentes em seu estado original.