От MongoDB 4.4 можете да използвате $bsonSize
оператор на конвейер за агрегиране, за да върне размера на даден документ в байтове.
$bsonSize
приема всеки валиден израз, стига да се разрешава до обект или null
.
Пример
Да предположим, че имаме колекция, наречена bars
със следния документ:
{ "_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" } ] }
Можем да видим, че location
полето съдържа документ. И reviews
поле съдържа масив от документи.
Нека използваме $bsonSize
оператор, за да проверите размера на location
поле:
db.bars.aggregate([
{
$project: {
"locationSize": { $bsonSize: "$location" }
}
}
])
Резултат:
{ "_id" : 1, "locationSize" : 61 }
В този случай размерът на location
полето е 61 байта.
Обекти в масиви
Ето пример за получаване на размера на документ, който е елемент от масив:
db.bars.aggregate([
{
$project: {
"review": { $arrayElemAt: [ "$reviews", 0 ] },
"reviewSize": { $bsonSize: { $arrayElemAt: [ "$reviews", 0 ] } }
}
}
]).pretty()
Резултат:
{ "_id" : 1, "review" : { "name" : "Steve", "date" : "20 December, 2020", "rating" : 5, "comments" : "Great vibe." }, "reviewSize" : 91 }
В този случай използваме $arrayElemAt
за да върнете действителния преглед и след това отново, за да върнете размера на този преглед.
Масивите на MongoDB са базирани на нула, така че прегледът е първият преглед.
Вземете размера на документа от най-високо ниво
Можем да използваме $$ROOT
системна променлива за препращане към документ от най-високо ниво – или основен документ. Това е документът, който в момента се обработва от конвейера.
Следователно можем да предадем $$ROOT
променлива към $bsonSize
за да получите размера на целия документ, който в момента се обработва.
Пример:
db.bars.aggregate([
{
$project: {
"rootSize": { $bsonSize: "$$ROOT" }
}
}
])
Резултат:
{ "_id" : 1, "rootSize" : 502 }
В този случай документът е 502 байта.
Грешни типове данни
Както споменахме, $bsonSize
приема всеки валиден израз, стига да се разрешава до обект или null
.
Ето пример за това какво се случва, ако предоставите израз, който се разрешава до различен тип BSON:
db.bars.aggregate([
{
$project: {
"nameSize": { $bsonSize: "$name" }
}
}
])
Резултат:
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
В този случай се опитахме да намерим размера на низ, но това не е един от поддържаните типове BSON, така че получаваме грешка.
Не всичко обаче е загубено. Можем да използваме $binarySize
за да получите размера на низ.
Вземете общия размер на всички документи в колекция
Да предположим, че имаме колекция, наречена cats
със следните документи:
{ "_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") }
Както беше показано по-горе, можем да използваме $$ROOT
за да върнете документа от най-високо ниво, който се обработва в момента:
db.cats.aggregate([
{
$project: {
"rootSize": { $bsonSize: "$$ROOT" }
}
}
])
Резултат:
{ "_id" : 1, "rootSize" : 58 } { "_id" : 2, "rootSize" : 49 } { "_id" : 3, "rootSize" : 51 } { "_id" : 4, "rootSize" : 48 } { "_id" : 5, "rootSize" : 40 } { "_id" : 6, "rootSize" : 48 }
Но можем да получим и общата сума размер на всички документи в колекцията.
Можем да постигнем това по следния начин:
db.cats.aggregate([
{
$group: {
"_id": null,
"rootSize": { $sum: { $bsonSize: "$$ROOT" } }
}
}
])
Резултат:
{ "_id" : null, "rootSize" : 294 }
Тук групирахме резултатите с помощта на $group
оператор и предоставяне на _id
от null
. Можехме да използваме всяка друга константна стойност.
Използвахме и $sum
за изчисляване на комбинираните размери на различните документи.
Виждаме, че общият размер на всички документи в колекцията е 294, което можем да потвърдим, като добавим резултатите в предишния пример.
Метод Object.bsonSize()
Друг начин да получите размера на документа е да използвате Object.bsonSize()
метод.