In MongoDB, il $max
l'operatore della pipeline di aggregazione restituisce il valore massimo da un'espressione.
Sintassi
Il $max
operatore supporta due sintassi.
Sintassi 1:
{ $max: <expression> }
Sintassi 2:
{ $max: [ <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, $max
restituisce il valore massimo risultante dall'applicazione di un'espressione 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 di argomento singolo.
Documenti raggruppati
Questo esempio usa $max
insieme a $group
per restituire il valore massimo da 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 $max
per restituire il valore massimo del weight
campo per ogni gruppo:
db.pets.aggregate(
[
{
$group:
{
_id: "$type",
max: { $max: "$weight" }
}
}
]
)
Risultato:
{ "_id" : "Kangaroo", "max" : 200 } { "_id" : "Cat", "max" : 12 } { "_id" : "Dog", "max" : 30 }
Array
Questo esempio applica $max
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 $max
ai scores
campo in ogni documento:
db.players.aggregate(
[
{
$project:
{
player: 1,
max: { $max: "$scores" }
}
}
]
)
Risultato:
{ "_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 }
In questo caso, i primi quattro documenti hanno restituito il valore massimo dai 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 $max
con più di un argomento. $max
quindi restituisce il valore massimo da tutti gli argomenti forniti.
Supponiamo di avere una raccolta chiamata data
con il seguente documento:
{ "_id" : 1, "a" : 10, "b" : 500, "c" : -900, "d" : 4 }
Possiamo usare $max
per restituire il valore massimo da a
, b
, c
e d
campi:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
max: { $max: [ "$a", "$b", "$c", "$d" ] }
}
}
]
)
Risultato:
{ "_id" : 1, "max" : 500 }
In questo caso, 500
era il valore massimo.
Campi mancanti
Quando si utilizza la sintassi multi-argomento, $max
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(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
max: { $max: [ "$a", "$b", "$c", "$d", "$e" ] }
}
}
]
)
Risultato:
{ "_id" : 1, "max" : 500 }
In questo caso ho fornito un campo aggiuntivo ($e
) che non esiste nel documento. $max
calcolato il valore massimo in base ai campi rimanenti che fanno esistono.
Tuttavia, ecco cosa succede quando nessuno dei campi esistono:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
result: { $max: [ "$x", "$y", "$z" ] }
}
}
]
)
Risultato:
{ "_id" : 1, "result" : null }
Il risultato è null
.
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",
max: { $max: "$oops!" }
}
}
]
)
Risultato:
{ "_id" : "Dog", "max" : null } { "_id" : "Kangaroo", "max" : null } { "_id" : "Cat", "max" : null }
Confronto di diversi tipi
Il $max
l'operatore confronta sia il valore che il tipo. Quando i valori sono di tipo diverso, $max
calcola il valore massimo in base all'ordine di confronto BSON.
Supponiamo che la nostra collezione contenga i seguenti documenti:
{ "_id" : 2, "a" : 1, "b" : 2, "c" : 3, "d" : [ 1 ] } { "_id" : 3, "a" : 1, "b" : 2, "c" : 3, "d" : "1" } { "_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" }
Ad eccezione del documento 4, ciascuno di questi documenti utilizza tipi misti (ne esiste almeno un tipo diverso dagli altri nei campi dati). Il documento 4 utilizza le stringhe in tutti e quattro i campi.
Ecco cosa succede quando applichiamo $max
a quei documenti:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 2, 3, 4, 5, 6 ] } } },
{
$project:
{
max: { $max: [ "$a", "$b", "$c", "$d" ] }
}
}
]
)
Risultato:
{ "_id" : 2, "max" : [ 1 ] } { "_id" : 3, "max" : "1" } { "_id" : 4, "max" : "Two" } { "_id" : 5, "max" : ISODate("2000-01-03T23:30:15.100Z") } { "_id" : 6, "max" : ISODate("1999-01-03T23:30:15.100Z") }
il documento con un _id
di 2
, gli array sono maggiori dei numeri, quindi viene restituito l'array (anche se il suo elemento è un numero minore di alcuni degli altri numeri).
Documento 3:le stringhe sono maggiori dei numeri, quindi viene restituita la stringa.
Documento 4:Tutti i campi sono stringhe, quindi Two
è la stringa più grande.
Documento 5:vengono fornite due date e quindi viene restituita la data successiva.
Documento 6:In questo caso vengono forniti un oggetto Date e una stringa di data. Gli oggetti Date sono maggiori delle stringhe, quindi viene restituito l'oggetto Date (anche se la sua data è precedente a quella della stringa).
Stadi disponibili
$max
è disponibile nelle seguenti fasi:
$group
$project
$addFields
$set
$replaceRoot
$replaceWith
$match
fase che include un$expr
espressione