Desde MongoDB 4.4, puede usar $bsonSize
operador de canalización de agregación para devolver el tamaño de un documento determinado en bytes.
$bsonSize
acepta cualquier expresión válida siempre que se resuelva en un objeto o null
.
Ejemplo
Supongamos que tenemos una colección llamada bars
con el siguiente 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" } ] }
Podemos ver que la location
campo contiene un documento. Y las reviews
El campo contiene una serie de documentos.
Usemos el $bsonSize
operador para verificar el tamaño de la location
campo:
db.bars.aggregate([
{
$project: {
"locationSize": { $bsonSize: "$location" }
}
}
])
Resultado:
{ "_id" : 1, "locationSize" : 61 }
En este caso, el tamaño de la location
el campo es de 61 bytes.
Objetos en matrices
Aquí hay un ejemplo de cómo obtener el tamaño de un documento que es un elemento de una matriz:
db.bars.aggregate([
{
$project: {
"review": { $arrayElemAt: [ "$reviews", 0 ] },
"reviewSize": { $bsonSize: { $arrayElemAt: [ "$reviews", 0 ] } }
}
}
]).pretty()
Resultado:
{ "_id" : 1, "review" : { "name" : "Steve", "date" : "20 December, 2020", "rating" : 5, "comments" : "Great vibe." }, "reviewSize" : 91 }
En este caso, usamos $arrayElemAt
para devolver la opinión real y, a continuación, de nuevo para devolver el tamaño de esa opinión.
Los arreglos de MongoDB están basados en cero, por lo que la revisión es la primera revisión.
Obtener el tamaño del documento de nivel superior
Podemos usar el $$ROOT
variable del sistema para hacer referencia al documento de nivel superior o documento raíz. Este es el documento que la canalización está procesando actualmente.
Por lo tanto, podemos pasar el $$ROOT
variable a $bsonSize
para obtener el tamaño de todo el documento que se está procesando actualmente.
Ejemplo:
db.bars.aggregate([
{
$project: {
"rootSize": { $bsonSize: "$$ROOT" }
}
}
])
Resultado:
{ "_id" : 1, "rootSize" : 502 }
En este caso, el documento es de 502 bytes.
Tipos de datos incorrectos
Como se mencionó, $bsonSize
acepta cualquier expresión válida siempre que se resuelva en un objeto o null
.
Este es un ejemplo de lo que sucede si proporciona una expresión que se resuelve en un tipo de BSON diferente:
db.bars.aggregate([
{
$project: {
"nameSize": { $bsonSize: "$name" }
}
}
])
Resultado:
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
En este caso, intentamos encontrar el tamaño de una cadena, pero ese no es uno de los tipos de BSON admitidos, por lo que recibimos un error.
Sin embargo, no todo está perdido. Podemos usar $binarySize
para obtener el tamaño de una cadena.
Obtener el tamaño total de todos los documentos de una colección
Supongamos que tenemos una colección llamada cats
con los siguientes documentos:
{ "_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") }
Como se mostró anteriormente, podemos usar $$ROOT
para devolver el documento de nivel superior que se está procesando actualmente:
db.cats.aggregate([
{
$project: {
"rootSize": { $bsonSize: "$$ROOT" }
}
}
])
Resultado:
{ "_id" : 1, "rootSize" : 58 } { "_id" : 2, "rootSize" : 49 } { "_id" : 3, "rootSize" : 51 } { "_id" : 4, "rootSize" : 48 } { "_id" : 5, "rootSize" : 40 } { "_id" : 6, "rootSize" : 48 }
Pero también podemos obtener el total tamaño de todos los documentos de la colección.
Podemos lograr esto de la siguiente manera:
db.cats.aggregate([
{
$group: {
"_id": null,
"rootSize": { $sum: { $bsonSize: "$$ROOT" } }
}
}
])
Resultado:
{ "_id" : null, "rootSize" : 294 }
Aquí, agrupamos los resultados usando el $group
operador y proporcionando un _id
de null
. Podríamos haber usado cualquier otro valor constante.
También usamos $sum
para calcular los tamaños combinados de los distintos documentos.
Podemos ver que el tamaño total de todos los documentos de la colección es 294, lo que podemos confirmar sumando los resultados del ejemplo anterior.
Método Object.bsonSize()
Otra forma de obtener el tamaño de un documento es usar Object.bsonSize()
método.