MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Operador de pipeline de agregação do MongoDB $max


No MongoDB, o $max operador de pipeline de agregação retorna o valor máximo de uma expressão.

Sintaxe


O $max O operador suporta duas sintaxes.

Sintaxe 1:
{ $max: <expression> } 

Sintaxe 2:
{ $max: [ <expression1>, <expression2> ... ]  } 

A primeira sintaxe aceita um argumento e a segunda sintaxe aceita vários argumentos.

Quando usado no $group stage, você só pode usar a primeira sintaxe. Neste caso, $max retorna o valor máximo resultante da aplicação de uma expressão a cada documento em um grupo de documentos que compartilham o mesmo grupo por chave.

Exemplos de sintaxe 1 (argumento único)


Aqui estão alguns exemplos que usam a sintaxe de argumento único.

Documentos agrupados


Este exemplo usa $max em conjunto com $group para retornar o valor máximo de um grupo de documentos agrupados por chave.

Suponha que tenhamos uma coleção chamada pets com os seguintes documentos:
{ "_id" :1, "name" :"Wag", "type" :"Dog", "weight" :20 }{ "_id" :2, "name" :"Latido", "tipo" :"Dog", "weight" :10 }{ "_id" :3, "name" :"Miau", "type" :"Cat", "weight" :7 }{ "_id" :4, "name" :"Scratch", "type" :"Cat", "weight" :8 }{ "_id" :5, "name" :"Bruce", "type" :"Canguru", "weight" :100 }{ " _id" :6, "name" :"Hop", "type" :"Canguru", "peso" :130 }{ "_id" :7, "name" :"Punch", "type" :"Canguru", "weight" :200 }{ "_id" :8, "name" :"Snap", "type" :"Gato", "weight" :12 }{ "_id" :9, "name" :"Ruff", "type" :"Cão", "peso" :30 }

Podemos agrupar esses documentos por seu type campo e, em seguida, use $max para retornar o valor máximo do weight campo para cada grupo:
db.pets.aggregate(
   [
     {
       $group:
          {
            _id: "$type",
            max: { $max: "$weight" }
          }
     }
   ]
) 

Resultado:
{ "_id" :"Canguru", "max" :200 }{ "_id" :"Gato", "max" :12 }{ "_id" :"Cão", "max" :30 } 

Matrizes


Este exemplo se aplica a $max para um único documento que contém um campo com uma matriz de valores.

Esta opção só está disponível ao usar a sintaxe de argumento único. As matrizes são ignoradas ao usar a sintaxe de vários argumentos (mais sobre isso abaixo).

Suponha que tenhamos uma coleção chamada players com os seguintes 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 $max para as scores campo em cada documento:
db.players.aggregate(
   [
     {
       $project:
          {
            player: 1,
            max: { $max: "$scores" }
          }
     }
   ]
) 

Resultado:
{ "_id" :1, "player" :"Homer", "max" :8 }{ "_id" :2, "player" :"Marge", "max" :18 }{ "_id" :3, "player" :"Bart", "max" :15 }{ "_id" :4, "player" :"Brian", "max" :7 }{ "_id" :5, "player" :"Farnsworth ", "max" :null }{ "_id" :6, "player" :"Meg", "max" :null }{ "_id" :7, "player" :"Ron", "max" :null } 

Nesse caso, os quatro primeiros documentos retornaram o valor máximo dos diversos números que estavam em seus respectivos arrays.

No caso do documento 4, era o mesmo que o número, pois havia apenas um número no array.

O documento 5 retornou null porque fornecemos um array vazio.

O documento 6 retornou null porque fornecemos null como o argumento.

O documento 7 retornou null porque o campo nem existia.

Exemplo de sintaxe 2 (vários argumentos)


A segunda sintaxe envolve fornecer $max com mais de um argumento. $max em seguida, retorna o valor máximo de todos os argumentos fornecidos.

Suponha que tenhamos uma coleção chamada data com o seguinte documento:
{ "_id":1, "a":10, "b":500, "c":-900, "d":4 }

Podemos usar $max para retornar o valor máximo do a , b , c e d Campos:
db.data.aggregate(
   [
     { $match: { _id: { $in: [ 1 ] } } },
     {
       $project:
          {
            max: { $max: [ "$a", "$b", "$c", "$d" ] }
          }
     }
   ]
) 

Resultado:
{ "_id" :1, "max" :500 }

Nesse caso, 500 foi o valor máximo.

Campos ausentes


Ao usar a sintaxe de vários argumentos, $max ignora quaisquer campos ausentes. Ou seja, se você fornecer um campo que não existe, ele o ignora. Se nenhum dos campos existir, ele retornará null .

Exemplo:
db.data.aggregate(
   [
     { $match: { _id: { $in: [ 1 ] } } },
     {
       $project:
          {
            max: { $max: [ "$a", "$b", "$c", "$d", "$e" ] }
          }
     }
   ]
) 

Resultado:
{ "_id" :1, "max" :500 }

Neste caso forneci um campo extra ($e ) que não existe no documento. $max calculou o valor máximo com base nos campos restantes que fazem existir.

No entanto, veja o que acontece quando nenhum dos campos existem:
db.data.aggregate(
   [
     { $match: { _id: { $in: [ 1 ] } } },
     {
       $project:
          {
            result: { $max: [ "$x", "$y", "$z" ] }
          }
     }
   ]
) 

Resultado:
{ "_id":1, "resultado":null }

O resultado é null .

Como vimos anteriormente, ao usar a sintaxe de argumento único, um campo ausente resulta em null .

Exemplo:
db.pets.aggregate(
   [
     {
       $group:
          {
            _id: "$type",
            max: { $max: "$oops!" }
          }
     }
   ]
) 

Resultado:
{ "_id" :"Cachorro", "max" :null }{ "_id" :"Canguru", "max" :null }{ "_id" :"Gato", "max" :null } 

Comparação de diferentes tipos


O $max O operador compara valor e tipo. Quando os valores são de tipos diferentes, $max calcula o valor máximo com base na ordem de comparação BSON.

Suponha que nossa coleção contenha os seguintes documentos:
{ "_id" :2, "a" :1, "b" :2, "c" :3, "d" :[ 1 ] }{ "_id" :3, "a" :1, " b" :2, "c" :3, "d" :"1" }{ "_id" :4, "a" :"Um", "b" :"Dois", "c" :"Três", "d" :"Quatro" }{ "_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"} 
Com exceção do documento 4, cada um desses documentos usa tipos mistos (há pelo menos um tipo diferente dos outros nos campos de dados). O Documento 4 usa strings em todos os quatro campos.

Veja o que acontece quando aplicamos $max a esses documentos:
db.data.aggregate(
   [
     { $match: { _id: { $in: [ 2, 3, 4, 5, 6 ] } } },
     {
       $project:
          {
            max: { $max: [ "$a", "$b", "$c", "$d" ] }
          }
     }
   ]
) 

Resultado:
{ "_id" :2, "max" :[ 1 ] }{ "_id" :3, "max" :"1" }{ "_id" :4, "max" :"Dois" }{ " _id" :5, "max" :ISODate("2000-01-03T23:30:15.100Z") }{ "_id" :6, "max" :ISODate("1999-01-03T23:30:15.100Z" ) }

o documento com um _id de 2 , arrays são maiores que números, então o array é retornado (mesmo que seu elemento seja um número menor que alguns dos outros números).

Documento 3:Strings são maiores que números e, portanto, a string é retornada.

Documento 4:Todos os campos são strings, então Two é a maior corda.

Documento 5:São fornecidas duas datas e, portanto, a data posterior é devolvida.

Documento 6:Neste caso, são fornecidos um objeto Date e uma string de data. Os objetos Date são maiores que as strings e, portanto, o objeto Date é retornado (mesmo que sua data seja anterior à da string).

Etapas disponíveis


$max está disponível nas seguintes etapas:
  • $group
  • $project
  • $addFields
  • $set
  • $replaceRoot
  • $replaceWith
  • $match estágio que inclui um $expr expressão