sql >> Database >  >> NoSQL >> MongoDB

MongoDB $avg Aggregation Pipeline Operator

In MongoDB is de $avg aggregatiepijplijnoperator berekent en retourneert de gemiddelde waarde van de opgegeven numerieke waarden.

Syntaxis

De $avg operator ondersteunt twee syntaxis.

Syntaxis 1:

{ $avg: <expression> }

Syntaxis 2:

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

De eerste syntaxis accepteert één argument en de tweede syntaxis accepteert meerdere argumenten.

Bij gebruik in de $group stadium, kunt u alleen de eerste syntaxis gebruiken. In dit geval, $avg retourneert het collectieve gemiddelde van alle numerieke waarden die het resultaat zijn van het toepassen van een opgegeven uitdrukking op elk document in een groep documenten die dezelfde groep op sleutel delen.

Voorbeelden van syntaxis 1 (enkel argument)

Hier zijn een paar voorbeelden die syntaxis 1 gebruiken.

Gegroepeerde documenten

Dit voorbeeld gebruikt $avg in combinatie met $group om het gemiddelde terug te geven van een groep documenten die op sleutel zijn gegroepeerd.

Stel dat we een verzameling hebben met de naam pets met de volgende documenten:

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

We kunnen deze documenten groeperen op hun type veld, en gebruik dan $avg om het gemiddelde gewicht van elke groep terug te geven:

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

Resultaat:

{ "_id" : "Dog", "average_weight" : 20 }
{ "_id" : "Cat", "average_weight" : 9 }
{ "_id" : "Kangaroo", "average_weight" : 143.33333333333334 }

Arrays

Dit voorbeeld is van toepassing op $avg naar een enkel document dat een veld met een reeks waarden bevat.

Deze optie is alleen beschikbaar bij gebruik van de syntaxis voor één argument. Arrays worden genegeerd bij gebruik van de syntaxis met meerdere argumenten (meer hierover hieronder).

Stel dat we een verzameling hebben met de naam players met de volgende documenten:

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

We kunnen $avg apply toepassen naar de scores veld in elk document:

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

Resultaat:

{ "_id" : 1, "player" : "Homer", "averageScore" : 4.142857142857143 }
{ "_id" : 2, "player" : "Marge", "averageScore" : 8.666666666666666 }
{ "_id" : 3, "player" : "Bart", "averageScore" : 6.333333333333333 }
{ "_id" : 4, "player" : "Brian", "averageScore" : 7 }
{ "_id" : 5, "player" : "Farnsworth", "averageScore" : null }
{ "_id" : 6, "player" : "Meg", "averageScore" : null }
{ "_id" : 7, "player" : "Ron", "averageScore" : null }

In dit geval gaven de eerste vier documenten het gemiddelde terug van de verschillende getallen die in hun respectievelijke arrays stonden.

In het geval van document 4 was dit hetzelfde als het nummer, omdat er maar één nummer in de array was.

Document 5 retourneerde null omdat we een lege array hebben opgegeven.

Document 6 retourneerde null omdat we null . hebben opgegeven als het argument.

Document 7 retourneerde null omdat het veld niet eens bestond.

Voorbeeld van syntaxis 2 (meerdere argumenten)

De tweede syntaxis omvat het verstrekken van $avg met meer dan één argument. $avg berekent vervolgens het gemiddelde op basis van alle opgegeven argumenten.

Stel dat we een verzameling hebben met de naam data met de volgende documenten:

{ "_id" : 1, "a" : 1, "b" : 2, "c" : 3, "d" : 4 }
{ "_id" : 2, "a" : 1, "b" : 2, "c" : 3, "d" : [ 4 ] }
{ "_id" : 3, "a" : 1, "b" : 2, "c" : 3, "d" : "Hey" }
{ "_id" : 4, "a" : "One", "b" : "Two", "c" : "Three", "d" : "Four" }

We kunnen $avg . gebruiken om het gemiddelde van de a . te retourneren , b , c , en d velden van elk document:

db.data.aggregate(
   [
     {
       $project:
          {
            avg: { $avg: [ "$a", "$b", "$c", "$d" ] }
          }
     }
   ]
)

Resultaat:

{ "_id" : 1, "avg" : 2.5 }
{ "_id" : 2, "avg" : 2 }
{ "_id" : 3, "avg" : 2 }
{ "_id" : 4, "avg" : null }

Document 1 retourneert het gemiddelde van de invoerwaarden van 1 , 2 , 3 , en 4 .

De volgende twee documenten retourneerden echter alleen het gemiddelde van de invoerwaarden van 1 , 2 , en 3 . De $avg operator negeerde hun d velden.

Dit komt omdat $avg negeert niet-numerieke waarden. Dus in dit geval negeerde het "Hey" in document 3 en het gemiddelde berekend uit de overige (numerieke) velden.

Wat betreft document 2, het is d veld bevat een array. Zoals gezegd, de $avg operator negeert arrays bij gebruik van de syntaxis met meerdere argumenten. Meer precies, het behandelt arrays als niet-numerieke waarden wanneer ze in deze context worden gebruikt, en $avg negeert niet-numerieke waarden.

Als alle waarden niet-numeriek zijn, dan $avg retourneert null . We kunnen dit zien met document 4.

Ontbrekende velden

Bij gebruik van de syntaxis met meerdere argumenten, $avg negeert eventuele ontbrekende velden. Dat wil zeggen, als u een veld opgeeft dat niet bestaat, wordt dit genegeerd. Als geen van de velden bestaat, retourneert het null .

Voorbeeld:

db.data.aggregate(
   [
     {
       $project:
          {
            avg: { $avg: [ "$a", "$b", "$c", "$d", "$e" ] }
          }
     }
   ]
)

Resultaat:

{ "_id" : 1, "avg" : 2.5 }
{ "_id" : 2, "avg" : 2 }
{ "_id" : 3, "avg" : 2 }
{ "_id" : 4, "avg" : null }

In dit geval heb ik een extra veld ($e ) die niet in de documenten voorkomt. $avg berekende het gemiddelde op basis van de resterende velden die doen bestaan.

Dit is echter wat er gebeurt als geen van de velden bestaat:

db.data.aggregate(
   [
     {
       $project:
          {
            result: { $avg: [ "$x", "$y", "$z" ] }
          }
     }
   ]
)

Resultaat:

{ "_id" : 1, "result" : null }
{ "_id" : 2, "result" : null }
{ "_id" : 3, "result" : null }
{ "_id" : 4, "result" : null }

Het resultaat is null voor alle documenten.

Zoals we eerder zagen, resulteert bij het gebruik van de syntaxis van één argument een ontbrekend veld in null .

Voorbeeld:

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

Resultaat:

{ "_id" : "Kangaroo", "avg" : null }
{ "_id" : "Cat", "avg" : null }
{ "_id" : "Dog", "avg" : null }

Beschikbare stadia

$avg is beschikbaar in de volgende fasen:

  • $group
  • $project
  • $addFields
  • $set
  • $replaceRoot
  • $replaceWith
  • $match fase met een $expr uitdrukking

  1. Database.yml verwijderen bij gebruik van Mongoid in Rails 3.2

  2. Socket.io migreren van 0.9.x naar 1.x, problemen met het configureren van RedisStore

  3. Gegevens opvragen uit MongoDB met GraphQL in Django:Get-Go (1)

  4. MongoDB kaart/verminderen over meerdere collecties?