sql >> Base de Datos >  >> NoSQL >> MongoDB

Operador de tubería de agregación MongoDB $min

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