Da MongoDB 4.4, puoi usare $bsonSize
operatore della pipeline di aggregazione per restituire la dimensione di un determinato documento in byte.
$bsonSize
accetta qualsiasi espressione valida purché si risolva in un oggetto o in null
.
Esempio
Supponiamo di avere una collezione chiamata bars
con il seguente documento:
{ "_id" : 1, "name" : "Boardwalk Social", "location" : { "type" : "Point", "coordinates" : [ -16.919297718553366, 145.77675259719823 ] }, "categories" : [ "Bar", "Restaurant", "Hotel" ], "reviews" : [ { "name" : "Steve", "date" : "20 December, 2020", "rating" : 5, "comments" : "Great vibe." }, { "name" : "Lisa", "date" : "25 October, 2020", "rating" : 3, "comments" : "They just raised their prices :(" }, { "name" : "Kim", "date" : "21 October, 2020", "rating" : 4, "comments" : "Nice for Friday happy hour" } ] }
Possiamo vedere che la location
campo contiene un documento. E le reviews
contiene un array di documenti.
Usiamo il $bsonSize
operatore per verificare la dimensione della location
campo:
db.bars.aggregate([
{
$project: {
"locationSize": { $bsonSize: "$location" }
}
}
])
Risultato:
{ "_id" : 1, "locationSize" : 61 }
In questo caso, la dimensione della location
il campo è 61 byte.
Oggetti negli array
Ecco un esempio di come ottenere le dimensioni di un documento che è un elemento di un array:
db.bars.aggregate([
{
$project: {
"review": { $arrayElemAt: [ "$reviews", 0 ] },
"reviewSize": { $bsonSize: { $arrayElemAt: [ "$reviews", 0 ] } }
}
}
]).pretty()
Risultato:
{ "_id" : 1, "review" : { "name" : "Steve", "date" : "20 December, 2020", "rating" : 5, "comments" : "Great vibe." }, "reviewSize" : 91 }
In questo caso, utilizziamo $arrayElemAt
per restituire la recensione effettiva, e poi di nuovo per restituire la dimensione di quella recensione.
Gli array MongoDB sono a base zero, quindi la recensione è la prima.
Ottieni la dimensione del documento di primo livello
Possiamo usare il $$ROOT
variabile di sistema per fare riferimento al documento di livello superiore o al documento radice. Questo è il documento attualmente in fase di elaborazione da parte della pipeline.
Pertanto, possiamo passare il $$ROOT
variabile a $bsonSize
per ottenere le dimensioni dell'intero documento attualmente in elaborazione.
Esempio:
db.bars.aggregate([
{
$project: {
"rootSize": { $bsonSize: "$$ROOT" }
}
}
])
Risultato:
{ "_id" : 1, "rootSize" : 502 }
In questo caso, il documento è di 502 byte.
Tipi di dati errati
Come accennato, $bsonSize
accetta qualsiasi espressione valida purché si risolva in un oggetto o null
.
Ecco un esempio di cosa succede se fornisci un'espressione che si risolve in un tipo BSON diverso:
db.bars.aggregate([
{
$project: {
"nameSize": { $bsonSize: "$name" }
}
}
])
Risultato:
Error: command failed: { "ok" : 0, "errmsg" : "$bsonSize requires a document input, found: string", "code" : 31393, "codeName" : "Location31393" } : aggregate failed : [email protected]/mongo/shell/utils.js:25:13 [email protected]/mongo/shell/assert.js:18:14 [email protected]/mongo/shell/assert.js:618:17 [email protected]/mongo/shell/assert.js:708:16 [email protected]/mongo/shell/db.js:266:5 [email protected]/mongo/shell/collection.js:1046:12 @(shell):1:1
In questo caso, abbiamo provato a trovare la dimensione di una stringa, ma non è uno dei tipi BSON supportati, quindi otteniamo un errore.
Tuttavia, non tutto è perduto. Possiamo usare $binarySize
per ottenere la dimensione di una stringa.
Ottieni la dimensione totale di tutti i documenti in una raccolta
Supponiamo di avere una collezione chiamata cats
con i seguenti documenti:
{ "_id" : 1, "name" : "Scratch", "born" : "March, 2020" } { "_id" : 2, "name" : "Meow", "weight" : 30 } { "_id" : 3, "name" : "Fluffy", "height" : 15 } { "_id" : 4, "name" : "Sox", "weight" : 40 } { "_id" : 5, "name" : null, "weight" : 20 } { "_id" : 6, "height" : 20, "born" : ISODate("2021-01-03T23:30:15.123Z") }
Come mostrato in precedenza, possiamo utilizzare $$ROOT
per restituire il documento di primo livello attualmente in elaborazione:
db.cats.aggregate([
{
$project: {
"rootSize": { $bsonSize: "$$ROOT" }
}
}
])
Risultato:
{ "_id" : 1, "rootSize" : 58 } { "_id" : 2, "rootSize" : 49 } { "_id" : 3, "rootSize" : 51 } { "_id" : 4, "rootSize" : 48 } { "_id" : 5, "rootSize" : 40 } { "_id" : 6, "rootSize" : 48 }
Ma possiamo anche ottenere il totale dimensione di tutti i documenti della collezione.
Possiamo raggiungere questo obiettivo come segue:
db.cats.aggregate([
{
$group: {
"_id": null,
"rootSize": { $sum: { $bsonSize: "$$ROOT" } }
}
}
])
Risultato:
{ "_id" : null, "rootSize" : 294 }
Qui, abbiamo raggruppato i risultati usando il $group
operatore e fornendo un _id
di null
. Avremmo potuto utilizzare qualsiasi altro valore costante.
Abbiamo anche usato $sum
per calcolare le dimensioni combinate dei vari documenti.
Possiamo vedere che la dimensione totale di tutti i documenti nella raccolta è 294, che possiamo confermare sommando i risultati nell'esempio precedente.
Metodo Object.bsonSize()
Un altro modo per ottenere le dimensioni di un documento è utilizzare Object.bsonSize()
metodo.