MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Operatore della pipeline di aggregazione $avg MongoDB

In MongoDB, il $avg l'operatore della pipeline di aggregazione calcola e restituisce il valore medio dei valori numerici specificati.

Sintassi

Il $avg operatore supporta due sintassi.

Sintassi 1:

{ $avg: <expression> }

Sintassi 2:

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

La prima sintassi accetta un argomento e la seconda sintassi accetta più argomenti.

Se utilizzato nel $group stage, puoi usare solo la prima sintassi. In questo caso, $avg restituisce la media collettiva di tutti i valori numerici risultanti dall'applicazione di un'espressione specificata a ciascun documento in un gruppo di documenti che condividono lo stesso gruppo per chiave.

Esempi di sintassi 1 (argomento singolo)

Ecco un paio di esempi che utilizzano la sintassi 1.

Documenti raggruppati

Questo esempio usa $avg insieme a $group per restituire la media di un gruppo di documenti raggruppati per chiave.

Supponiamo di avere una collezione chiamata pets con i seguenti documenti:

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

Possiamo raggruppare questi documenti in base al loro type campo, quindi usa $avg per restituire il peso medio di ogni gruppo:

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

Risultato:

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

Array

Questo esempio applica $avg in un singolo documento che contiene un campo con una matrice di valori.

Questa opzione è disponibile solo quando si utilizza la sintassi di argomento singolo. Gli array vengono ignorati quando si utilizza la sintassi multi-argomento (ne parleremo più avanti).

Supponiamo di avere una collezione chiamata players con i seguenti documenti:

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

Possiamo applicare $avg ai scores campo in ogni documento:

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

Risultato:

{ "_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 questo caso, i primi quattro documenti hanno restituito la media dei vari numeri che erano nei rispettivi array.

Nel caso del documento 4, questo era lo stesso del numero, perché c'era un solo numero nell'array.

Il documento 5 ha restituito null perché abbiamo fornito un array vuoto.

Il documento 6 ha restituito null perché abbiamo fornito null come argomento.

Il documento 7 ha restituito null perché il campo non esisteva nemmeno.

Esempio di sintassi 2 (argomenti multipli)

La seconda sintassi prevede di fornire $avg con più di un argomento. $avg quindi calcola la media in base a tutti gli argomenti forniti.

Supponiamo di avere una raccolta chiamata data con i seguenti documenti:

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

Possiamo usare $avg per restituire la media di a , b , c e d campi di ogni documento:

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

Risultato:

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

Il documento 1 restituisce la media dei valori di input di 1 , 2 , 3 e 4 .

Tuttavia, i due documenti successivi hanno restituito solo la media dei valori di input di 1 , 2 e 3 . Il $avg l'operatore ha ignorato il suo d campi.

Questo perché $avg ignora i valori non numerici. Quindi in questo caso ha ignorato "Hey" nel documento 3 e calcolato la media dai restanti campi (numerici).

Come per il documento 2, il suo d campo contiene una matrice. Come accennato, il $avg l'operatore ignora gli array quando si utilizza la sintassi multi-argomento. Più precisamente, tratta gli array come valori non numerici se usati in questo contesto e $avg ignora i valori non numerici.

Se tutti i valori non sono numerici, allora $avg restituisce null . Possiamo vederlo con il documento 4.

Campi mancanti

Quando si utilizza la sintassi multi-argomento, $avg ignora tutti i campi mancanti. Cioè, se fornisci un campo che non esiste, lo ignora. Se nessuno dei campi esiste, restituisce null .

Esempio:

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

Risultato:

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

In questo caso ho fornito un campo aggiuntivo ($e ) che non esiste nei documenti. $avg ha calcolato la media in base ai campi rimanenti che fanno esistono.

Tuttavia, ecco cosa succede quando nessuno dei campi esistono:

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

Risultato:

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

Il risultato è null per tutti i documenti.

Come abbiamo visto in precedenza, quando si utilizza la sintassi a argomento singolo, un campo mancante risulta null .

Esempio:

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

Risultato:

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

Stadi disponibili

$avg è disponibile nelle seguenti fasi:

  • $group
  • $project
  • $addFields
  • $set
  • $replaceRoot
  • $replaceWith
  • $match fase che include un $expr espressione