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 para encontrar documentos $expr na movies collection 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 agregação pipeline fornece ao operador para expressar instruções condicionais.$cond Usando $expr com o operador, você pode especificar um filtro condicional para sua declaração de $cond 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 para calcular a pontuação ponderada com base $cond em imdb.votes e para retornar documentos cuja pontuação ponderada $gt calculada é maior 9 que:
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 9 que:
[ { 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 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 $cond original.