En MongoDB, el $min
El operador de canalización de agregación devuelve el valor mínimo de una expresión.
Sintaxis
El $min
operador admite dos sintaxis.
Sintaxis 1:
{ $min: <expression> }
Sintaxis 2:
{ $min: [ <expression1>, <expression2> ... ] }
La primera sintaxis acepta un argumento y la segunda sintaxis acepta múltiples argumentos.
Cuando se usa en el $group
etapa, solo puede usar la primera sintaxis. En este caso, $min
devuelve el valor mínimo que resulta de aplicar una expresión a cada documento en un grupo de documentos que comparten el mismo grupo por clave.
Ejemplos de sintaxis 1 (argumento único)
Aquí hay un par de ejemplos que usan la sintaxis de un solo argumento.
Documentos agrupados
Este ejemplo usa $min
junto con $group
para devolver el valor mínimo de un grupo de documentos que se agrupan por clave.
Supongamos que tenemos una colección llamada pets
con los siguientes documentos:
{ "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 } { "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 } { "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 } { "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 } { "_id" : 5, "name" : "Bruce", "type" : "Kangaroo", "weight" : 100 } { "_id" : 6, "name" : "Hop", "type" : "Kangaroo", "weight" : 130 } { "_id" : 7, "name" : "Punch", "type" : "Kangaroo", "weight" : 200 } { "_id" : 8, "name" : "Snap", "type" : "Cat", "weight" : 12 } { "_id" : 9, "name" : "Ruff", "type" : "Dog", "weight" : 30 }
Podemos agrupar estos documentos por su type
y luego use $min
para devolver el valor mínimo del weight
campo para cada grupo:
db.pets.aggregate(
[
{
$group:
{
_id: "$type",
min: { $min: "$weight" }
}
}
]
)
Resultado:
{ "_id" : "Kangaroo", "min" : 100 } { "_id" : "Dog", "min" : 10 } { "_id" : "Cat", "min" : 7 }
Arreglos
Este ejemplo aplica $min
a un solo documento que contiene un campo con una matriz de valores.
Esta opción solo está disponible cuando se utiliza la sintaxis de argumento único. Las matrices se ignoran cuando se usa la sintaxis de múltiples argumentos (más sobre esto a continuación).
Supongamos que tenemos una colección llamada players
con los siguientes documentos:
{ "_id" : 1, "player" : "Homer", "scores" : [ 1, 7, 2, 3, 8, 7, 1 ] } { "_id" : 2, "player" : "Marge", "scores" : [ 0, 1, 8, 17, 18, 8 ] } { "_id" : 3, "player" : "Bart", "scores" : [ 15, 11, 8, 0, 1, 3 ] } { "_id" : 4, "player" : "Brian", "scores" : [ 7 ] } { "_id" : 5, "player" : "Farnsworth", "scores" : [ ] } { "_id" : 6, "player" : "Meg", "scores" : null } { "_id" : 7, "player" : "Ron" }
Podemos aplicar $min
a las scores
campo en cada documento:
db.players.aggregate(
[
{
$project:
{
player: 1,
min: { $min: "$scores" }
}
}
]
)
Resultado:
{ "_id" : 1, "player" : "Homer", "min" : 1 } { "_id" : 2, "player" : "Marge", "min" : 0 } { "_id" : 3, "player" : "Bart", "min" : 0 } { "_id" : 4, "player" : "Brian", "min" : 7 } { "_id" : 5, "player" : "Farnsworth", "min" : null } { "_id" : 6, "player" : "Meg", "min" : null } { "_id" : 7, "player" : "Ron", "min" : null }
En este caso, los primeros cuatro documentos devolvieron el valor mínimo de los varios números que estaban en sus respectivas matrices.
En el caso del documento 4, este era el mismo que el número, porque solo había un número en la matriz.
El documento 5 devolvió null
porque proporcionamos una matriz vacía.
El documento 6 devolvió null
porque proporcionamos null
como argumento.
El documento 7 devolvió null
porque el campo ni siquiera existía.
Ejemplo de sintaxis 2 (múltiples argumentos)
La segunda sintaxis consiste en proporcionar $min
con más de un argumento. $min
luego devuelve el valor mínimo de todos los argumentos suministrados.
Supongamos que tenemos una colección llamada data
con el siguiente documento:
{ "_id" : 1, "a" : 10, "b" : 500, "c" : -900, "d" : 4 }
Podemos usar $min
para devolver el valor mínimo de a
, b
, c
y d
campos:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
min: { $min: [ "$a", "$b", "$c", "$d" ] }
}
}
]
)
Resultado:
{ "_id" : 1, "min" : -900 }
En este caso, -900
era el valor mínimo.
Campos faltantes
Al usar la sintaxis de varios argumentos, $min
ignora cualquier campo faltante. Es decir, si proporciona un campo que no existe, lo ignora. Si ninguno de los campos existe, devuelve null
.
Ejemplo:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
min: { $min: [ "$a", "$b", "$c", "$d", "$e" ] }
}
}
]
)
Resultado:
{ "_id" : 1, "min" : -900 }
En este caso proporcioné un campo extra ($e
) que no existe en el documento. $min
calculó el valor mínimo en función de los campos restantes que hacen existir.
Sin embargo, esto es lo que sucede cuando ninguno de los campos existen:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
result: { $min: [ "$x", "$y", "$z" ] }
}
}
]
)
Resultado:
{ "_id" : 1, "result" : null }
El resultado es null
.
Como vimos anteriormente, al usar la sintaxis de un solo argumento, un campo faltante da como resultado null
.
Ejemplo:
db.pets.aggregate(
[
{
$group:
{
_id: "$type",
min: { $min: "$oops!" }
}
}
]
)
Resultado:
{ "_id" : "Dog", "min" : null } { "_id" : "Cat", "min" : null } { "_id" : "Kangaroo", "min" : null }
Comparando diferentes tipos
El $min
El operador compara tanto el valor como el tipo. Cuando los valores son de diferentes tipos, $min
calcula el valor mínimo en función del orden de comparación de BSON.
Supongamos que nuestra colección contiene los siguientes documentos:
{ "_id" : 2, "a" : 1, "b" : 2, "c" : 3, "d" : [ 0 ] } { "_id" : 3, "a" : 1, "b" : 2, "c" : 3, "d" : "0" } { "_id" : 4, "a" : "One", "b" : "Two", "c" : "Three", "d" : "Four" } { "_id" : 5, "a" : ISODate("1999-01-03T23:30:15.100Z"), "b" : ISODate("2000-01-03T23:30:15.100Z") } { "_id" : 6, "a" : ISODate("1999-01-03T23:30:15.100Z"), "b" : "2000-01-03T23:30:15.100Z" }
Con la excepción del documento 4, cada uno de esos documentos usa tipos mixtos (hay al menos un tipo que es diferente a los demás en los campos de datos). El documento 4 usa cadenas en los cuatro campos.
Esto es lo que sucede cuando aplicamos $min
a esos documentos:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 2, 3, 4, 5, 6 ] } } },
{
$project:
{
min: { $min: [ "$a", "$b", "$c", "$d" ] }
}
}
]
)
Resultado:
{ "_id" : 2, "min" : 1 } { "_id" : 3, "min" : 1 } { "_id" : 4, "min" : "Four" } { "_id" : 5, "min" : ISODate("1999-01-03T23:30:15.100Z") } { "_id" : 6, "min" : "2000-01-03T23:30:15.100Z" }
Respecto al documento con un _id
de 2
, los números son menores que las matrices, por lo que el número 1
se devuelve (aunque la matriz contiene un número que es menor que todos los demás números).
Documento 3:los números son menores que las cadenas, por lo que se devuelve el número más bajo.
Documento 4:Todos los campos son cadenas, por lo que Four
es la cadena mínima.
Documento 5:se proporcionan dos fechas, por lo que se devuelve la fecha anterior.
Documento 6:en este caso, se proporcionan un objeto Fecha y una cadena de fecha. Las cadenas son menores que los objetos de fecha, por lo que se devuelve la cadena (aunque su fecha sea posterior a la del objeto de fecha).
Etapas disponibles
$min
está disponible en las siguientes etapas:
$group
$project
$addFields
$set
$replaceRoot
$replaceWith
$match
etapa que incluye un$expr
expresión