Docs Menu
Docs Home
/ /

$expr

Modificado en la versión 5.0.

$expr

Permite el uso de expresiones dentro de un predicado de consulta.

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.

{ $expr: { <expression> } }

Los argumentos pueden ser cualquier expresión válida.

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 let debe resolverse en una constante.

    Por ejemplo, una comparación entre $a y un valor constante puede utilizar un índice, pero una comparación entre $a y $b no puede.

  • Los índices no se utilizan para comparaciones donde el operando let se resuelve en un valor vacío o faltante.

  • No se utilizan índicesmulticlave, parciales o dispersos.

$expr puede contener expresiones que comparen campos del mismo documento.

Crea una colección monthlyBudget con estos 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 }
] )

La siguiente operación utiliza $expr para encontrar documentos donde el monto de spent excede el budget:

db.monthlyBudget.find( { $expr: { $gt: [ "$spent" , "$budget" ] } } )

Salida:

{ _id : 1, category : "food", budget : 400, spent : 450 }
{ _id : 2, category : "drinks", budget : 100, spent : 150 }
{ _id : 5, category : "travel", budget : 200, spent : 650 }

Al definir un filtro de query, algunas queries requieren la capacidad de ejecutar lógica condicional. El pipeline de agregación proporciona el operador $cond para expresar instrucciones condicionales. Al utilizar $expr con el operador $cond, se puede especificar un filtro condicional para la instrucción de query.

Crea una colección de ejemplo supplies con los siguientes documentos:

db.supplies.insertMany( [
{ _id : 1, item : "binder", qty : Int32("100"), price : Decimal128("12") },
{ _id : 2, item : "notebook", qty : Int32("200"), price : Decimal128("8") },
{ _id : 3, item : "pencil", qty : Int32("50"), price : Decimal128("6") },
{ _id : 4, item : "eraser", qty : Int32("150"), price : Decimal128("3") },
{ _id : 5, item : "legal pad", qty : Int32("42"), price : Decimal128("10") }
] )

Supongamos que para una próxima venta el mes siguiente, quieres descontar los precios de tal forma que:

  • Si qty es mayor o igual a 100, el precio con descuento será el 50% del price.

  • Si qty es menor que 100, el precio con descuento es el 75% de price.

Antes de aplicar los descuentos, se necesita saber qué artículos de la colección supplies tienen un precio con descuento inferior a 5.

El siguiente ejemplo utiliza $expr con $cond para calcular el precio con descuento basado en el qty y $lt para devolver documentos cuyo precio de descuento calculado sea inferior a Decimal128("5"):

// Aggregation expression to calculate discounted price
let discountedPrice = {
$cond: {
if: { $gte: ["$qty", 100] },
then: { $multiply: ["$price", Decimal128("0.50")] },
else: { $multiply: ["$price", Decimal128("0.75")] }
}
};
// Query the supplies collection using the aggregation expression
db.supplies.find( { $expr: { $lt:[ discountedPrice, Decimal128("5") ] } });

La siguiente tabla muestra el precio con descuento de cada documento y si el precio con descuento es inferior a Decimal128("5") (es decir, si el documento cumple la condición de la query).

Documento
Precio con descuento
< Decimal128("5")

{"_id": 1, "item": "binder", "qty": 100, "price": Decimal128("12") }

Decimal128("6.00")

false

{"_id": 2, "item": "cuaderno", "qty": 200, "price": Decimal128("8") }

Decimal128("4.00")

true

{"_id": 3, "item": "pencil", "qty": 50, "price": Decimal128("6") }

Decimal128("4.50")

true

{"_id": 4, "item": "eraser", "qty": 150, "price": Decimal128("3") }

Decimal128("1.50")

true

{"_id": 5, "item": "legal pad", "qty": 42, "price": Decimal128("10") }

Decimal128("7.50")

false

La db.collection.find() operación devuelve los documentos cuyo precio de descuento calculado es menor que Decimal128("5"):

{ _id : 2, item : "notebook", qty : 200 , price : Decimal128("8") }
{ _id : 3, item : "pencil", qty : 50 , price : Decimal128("6") }
{ _id : 4, item : "eraser", qty : 150 , price : Decimal128("3") }

Aunque $cond calcula un precio con descuento en efectivo, ese precio no se refleja en los documentos que se devuelven. En su lugar, los documentos que se devuelven representan los documentos que coinciden en su estado original. La operación de búsqueda no devolvió los documentos binder o legal pad, ya que su precio con descuento era mayor que 5.

Volver

Misceláneo

En esta página