Definición
Modificado en la versión 5.0.
$exprPermite el uso del expresiones dentro de un query predicate.
Compatibilidad
Puedes usar $expr para implementaciones alojadas en los siguientes entornos:
MongoDB Atlas: El servicio totalmente gestionado para implementaciones de MongoDB en la nube
MongoDB Enterprise: La versión basada en suscripción y autogestionada de MongoDB
MongoDB Community: La versión de MongoDB con código fuente disponible, de uso gratuito y autogestionada.
Sintaxis
{ $expr: { <expression> } }
Los argumentos pueden ser cualquier expresión válida.
Comportamiento
$expr en operaciones $lookup
Cuando $expr aparece en una etapa $match que es parte de una subpipeline $lookup, $expr puede referirse a let variables definidas por la etapa $lookup. Para ver un ejemplo, consulta Usar varias condiciones de unión y una subconsulta correlacionada.
Los operadores de comparación $eq, $lt, $lte, $gt y $gte colocados en un operador $expr pueden utilizar un índice en la colección from referenciada en una etapa $lookup. Limitaciones:
Los índices solo pueden utilizarse para comparaciones entre campos y constantes, por lo que el operando
letdebe resolverse en una constante.Por ejemplo, una comparación entre
$ay un valor constante puede utilizar un índice, pero una comparación entre$ay$bno puede.Los índices no se utilizan para comparaciones donde el operando
letse resuelve en un valor vacío o faltante.No se utilizan índices multiclave, parciales o dispersos.
Ejemplos
Los ejemplos de esta página utilizan datos del conjunto de datos de muestra sample_mflix. Para obtener más información sobre cómo cargar este conjunto de datos en la implementación autogestionada de MongoDB, consultar Cargar el conjunto de datos de muestra. Si se realizó alguna modificación en las bases de datos de muestra, es posible que se deban descartar y volver a crear las bases de datos para ejecutar los ejemplos de esta página.
Compara dos campos de un solo documento
$expr puede contener expresiones que comparen campos del mismo documento.
La siguiente operación utiliza $expr para encontrar documentos en la colección movies donde la puntuación de Rotten Tomatoes por parte de los espectadores supera a la puntuación de los críticos:
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 } } } ]
Utiliza $expr con instrucciones condicionales
Algunas queries necesitan ejecutar lógica condicional al definir un filtro de query. La pipeline de agregación ofrece el $cond operador para expresar instrucciones condicionales. Utilizando $expr con el operador $cond, puedes especificar un filtro condicional para tu instrucción de query.
Supongamos que deseas calcular una puntuación ponderada para las películas de modo que las películas altamente calificadas con pocos votos no dominen los resultados:
Si
imdb.voteses mayor o igual a 1000, la puntuación ponderada es el totalimdb.rating.Si
imdb.voteses menor que 1000, la puntuación ponderada es 0.5 deimdb.rating.
Te gustaría saber qué películas de la colección movies tienen una puntuación ponderada superior a 9.
El siguiente ejemplo utiliza $expr con $cond para calcular la puntuación ponderada en función de imdb.votes y $gt para devolver documentos cuya puntuación ponderada calculada sea superior a 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)
La siguiente tabla muestra la puntuación ponderada de los documentos seleccionados y si la puntuación ponderada es mayor que 9 (es decir, si el documento cumple con la condición de la query).
Documento | Puntuación ponderada | > 9 |
|---|---|---|
| 9.3 |
|
| 9.2 |
|
| 8.9 |
|
| 9.5 |
|
| 4.55 |
|
La operación db.collection.find() devuelve 5 documentos cuyo puntaje ponderado calculado es superior a 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 } } ]
Aunque $cond calcula una puntuación ponderada, esa puntuación no se refleja en los documentos devueltos. En su lugar, los documentos devueltos representan los documentos coincidentes en su estado original.