MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

MongoDB $max оператор на конвейер за агрегиране

В MongoDB, $max Операторът на конвейера за агрегиране връща максималната стойност от израз.

Синтаксис

$max операторът поддържа два синтаксиса.

Синтаксис 1:

{ $max: <expression> } 

Синтаксис 2:

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

Първият синтаксис приема един аргумент, а вторият синтаксис приема множество аргументи.

Когато се използва в $group етап, можете да използвате само първия синтаксис. В този случай $max връща максималната стойност, която е резултат от прилагането на израз към всеки документ в група документи, които споделят една и съща група по ключ.

Примери за синтаксис 1 (единичен аргумент)

Ето няколко примера, които използват синтаксиса с един аргумент.

Групирани документи

Този пример използва $max във връзка с $group за да върнете максималната стойност от група документи, които са групирани по ключ.

Да предположим, че имаме колекция, наречена pets със следните документи:

{ "_id" :1, "name" :"Wag", "type" :"Dog", "weight" :20 }{ "_id" :2, "name" :"Bark", "type" :"Куче", "тегло" :10 }{ "_id" :3, "име" :"Мяу", "тип" :"Котка", "тегло" :7 }{ "_id" :4, "име" :"Scratch", "type" :"Cat", "weight" :8 }{ "_id" :5, "name" :"Bruce", "type" :"Kenguroo", "weight" :100 }{ " _id" :6, "name" :"Hop", "type" :"Kenguroo", "weight" :130 }{ "_id" :7, "name" :"Punch", "type" :"Kenguroo", "weight" :200 }{ "_id" :8, "name" :"Snap", "type" :"Cat", "weight" :12 }{ "_id" :9, "name" :"Ruff", "тип" :"Куче", "тегло" :30 }

Можем да групираме тези документи по техния type поле и след това използвайте $max за да върнете максималната стойност на weight поле за всяка група:

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

Резултат:

{ "_id" :"Кенгуру", "max" :200 }{ "_id" :"Котка", "max" :12 }{ "_id" :"Куче", "макс" :30 } 

Масиви

Този пример се прилага $max към един документ, който съдържа поле с масив от стойности.

Тази опция е налична само при използване на синтаксис на единичен аргумент. Масивите се игнорират, когато се използва синтаксисът с няколко аргумента (повече за това по-долу).

Да предположим, че имаме колекция, наречена players със следните документи:

{ "_id" :1, "player" :"Homer", "резултати" :[ 1, 7, 2, 3, 8, 7, 1 ] }{ "_id" :2, "player" :" Мардж", "резултати" :[ 0, 1, 8, 17, 18, 8 ] }{ "_id" :3, "играч" :"Барт", "резултати" :[ 15, 11, 8, 0, 1 , 3 ] }{ "_id" :4, "player" :"Brian", "cores" :[ 7 ] }{ "_id" :5, "player" :"Farnsworth", "cores" :[ ] }{ "_id" :6, "player" :"Мег", "резултати" :null }{ "_id" :7, "player" :"Рон" }

Можем да приложим $max към scores поле във всеки документ:

db.players.aggregate(
   [
     {
       $project:
          {
            player: 1,
            max: { $max: "$scores" }
          }
     }
   ]
) 

Резултат:

{ "_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 } 

В този случай първите четири документа върнаха максималната стойност от различните числа, които бяха в съответните им масиви.

В случай на документ 4 това беше същото като числото, защото имаше само едно число в масива.

Документ 5 върна null защото предоставихме празен масив.

Документ 6 върна null защото предоставихме null като аргумент.

Документ 7 върна null защото полето дори не е съществувало.

Пример за синтаксис 2 (множество аргументи)

Вторият синтаксис включва предоставяне на $max с повече от един аргумент. $max след това връща максималната стойност от всички предоставени аргументи.

Да предположим, че имаме колекция, наречена data със следния документ:

{ "_id" :1, "a" :10, "b" :500, "c" :-900, "d" :4 }

Можем да използваме $max за да върнете максималната стойност от a , b , c и d полета:

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

Резултат:

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

В този случай 500 беше максималната стойност.

Липсващи полета

Когато използвате синтаксиса с няколко аргумента, $max игнорира всички липсващи полета. Тоест, ако предоставите поле, което не съществува, то го игнорира. Ако нито едно от полетата не съществува, то връща null .

Пример:

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

Резултат:

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

В този случай предоставих допълнително поле ($e ), който не съществува в документа. $max изчислява максималната стойност въз основа на останалите полета, които правят съществуват.

Но ето какво се случва, когато няма от полетата съществуват:

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 1 ] } } },
     {
       $project:
          {
            result: { $max: [ "$x", "$y", "$z" ] }
          }
     }
   ]
) 

Резултат:

{ "_id" :1, "резултат":нула }

Резултатът е null .

Както видяхме по-рано, когато се използва синтаксисът с един аргумент, липсващо поле води до null .

Пример:

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

Резултат:

{ "_id" :"Куче", "max" :null }{ "_id" :"Кенгуру", "max" :null }{ "_id" :"Котка", "max" :null } 

Сравняване на различни типове

$max оператор сравнява стойността и типа. Когато стойностите са от различни типове, $max изчислява максималната стойност въз основа на реда за сравнение на BSON.

Да предположим, че нашата колекция съдържа следните документи:

{ "_id" :2, "a" :1, "b" :2, "c" :3, "d" :[ 1 ] }{ "_id" :3, "a" :1, " b" :2, "c" :3, "d" :"1" }{ "_id" :4, "a" :"Едно", "b" :"Две", "c" :"Три", "d" :"Четири" }{ "_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"} 

С изключение на документ 4, всеки от тези документи използва смесени типове (има поне един тип, който е различен от другите в полетата с данни). Документ 4 използва низове и в четирите полета.

Ето какво се случва, когато приложим $max към тези документи:

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 2, 3, 4, 5, 6 ] } } },
     {
       $project:
          {
            max: { $max: [ "$a", "$b", "$c", "$d" ] }
          }
     }
   ]
) 

Резултат:

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

документа с _id от 2 , масивите са по-големи от числата, така че масивът се връща (въпреки че неговият елемент е число, което е по-малко от някои от другите числа).

Документ 3:Низовете са по-големи от числата и затова низът се връща.

Документ 4:Всички полета са низове и така Two е най-големият низ.

Документ 5:Предоставени са две дати и така по-късната дата се връща.

Документ 6:В този случай се предоставят обект Date и низ от дата. Обектите за дата са по-големи от низовете и така обектът Date се връща (въпреки че датата му е по-ранна от низа).

Налични етапи

$max е наличен в следните етапи:

  • $group
  • $project
  • $addFields
  • $set
  • $replaceRoot
  • $replaceWith
  • $match етап, който включва $expr израз

  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Новият начин за управление на бази данни с отворен код

  2. Извикване на съхранена функция в mongodb

  3. Обработка на прекъсване/повторно свързване на MongoDB от Node

  4. Замяна на вграден документ в масив в MongoDB

  5. По-бърза ли е рамката на Mongodb Aggregation от map/reduce?