查询某个 collection 的文档大小分布
日常开发中,有时需要了解数据分布的一些特点,比如这个 colllection 里 documents 的平均大小、全部大小等,来调整程序的设计。
对于系统中已经存在大量数据的情况,这种提前分析数据分布模式的工作套路(最佳实践)可以帮助我们有的放矢的进行设计,避免不必要的过度设计或者进行更细致的设计。
如果想获得某个 collection 相关的各种存储统计信息,可以使用 **stats、collStats**。
如果想获取总计、平均等简单的统计信息,可以参考这里:https://www.mongodb.com/docs/manual/core/aggregation-pipeline/#std-label-aggregation-pipeline。
下面的命令可以显示 COLLECTION 中满足条件 status=’active’,字段 FIELD_A, FIELD_B 的数据大小的 Quantile analysis。
如果去掉第三行,就是对 COLLECTION 中所有文档数据的大小分布的统计。
//最大的Top10和百分比分布。
db.COLLECTION.aggregate([
{ $match: { "status": 'active' } },
{ $project: { _id: 1, FIELD_A: 1, FIELD_B: 1} },
{ $project: { documentSize: { $sum: { $bsonSize: "$$ROOT" } } } },
{ $sort: { documentSize: 1 } },
{ $group: { '_id': null, 'value': { '$push': '$documentSize' } } },
{ $project: { _id: 0,
"Top1": { $arrayElemAt: ["$value", { $floor: { $add: [-1, { $size: "$value" }] } } ] },
"Top2": { $arrayElemAt: ["$value", { $floor: { $add: [-2, { $size: "$value" }] } } ] },
"Top3": { $arrayElemAt: ["$value", { $floor: { $add: [-4, { $size: "$value" }] } } ] },
"Top4": { $arrayElemAt: ["$value", { $floor: { $add: [-5, { $size: "$value" }] } } ] },
"Top5": { $arrayElemAt: ["$value", { $floor: { $add: [-6, { $size: "$value" }] } } ] },
"Top6": { $arrayElemAt: ["$value", { $floor: { $add: [-7, { $size: "$value" }] } } ] },
"Top7": { $arrayElemAt: ["$value", { $floor: { $add: [-7, { $size: "$value" }] } } ] },
"Top8": { $arrayElemAt: ["$value", { $floor: { $add: [-8, { $size: "$value" }] } } ] },
"Top9": { $arrayElemAt: ["$value", { $floor: { $add: [-9, { $size: "$value" }] } } ] },
"Top10": { $arrayElemAt: ["$value", { $floor: { $add: [-10, { $size: "$value" }] } } ] },
"99-9%": { $arrayElemAt: ["$value", { $floor: { $multiply: [0.999, { $size: "$value" }] } } ] },
"99%": { $arrayElemAt: ["$value", { $floor: { $multiply: [0.99, { $size: "$value" }] } } ] },
"95%": { $arrayElemAt: ["$value", { $floor: { $multiply: [0.95, { $size: "$value" }] } } ] },
"90%": { $arrayElemAt: ["$value", { $floor: { $multiply: [0.90, { $size: "$value" }] } } ] },
"50%": { $arrayElemAt: ["$value", { $floor: { $multiply: [0.50, { $size: "$value" }] } } ] },
"25%": { $arrayElemAt: ["$value", { $floor: { $multiply: [0.25, { $size: "$value" }] } } ] },
} },
]);
对 MongoDB 4.2 以上版本,可以使用上述 aggrigation 语法进行统计。对 4.2 及其以下版本,需要使用 forEach 语句迭代进行计算。
对于不支持 Object.bsonsize 的 Mongo shell 可以使用 BSON.calculateObjectSize 进行替代。
// const BSON = require("bson");
var fieldsSize = []
var totalSize = 0
db.COLLECTION.find({ "status": 'A' }, { FIELD_A: 1, FIELD_B: 1}).forEach(function(doc)
{
var size = Object.bsonsize(doc)
// var size = BSON.calculateObjectSize(doc)
totalSize += size
fieldsSize.push(size)
});
var sortedData = fieldsSize.sort(function(a, b){return a-b});
var statistic = {
"Note": "The Collection Fields(FIELD_A, FIELD_B) Size Statistic Reuslt",
"numbOfDocs": sortedData.length,
"totalSize": (totalSize / 1024) + "KB " + (totalSize / (1024 * 1024)) + " MB",
"AVG:": Math.round(totalSize / sortedData.length),
"MIN": sortedData[0],
"TOP1": sortedData[sortedData.length - 1],
"TOP2": sortedData[sortedData.length - 2],
"TOP3": sortedData[sortedData.length - 3],
"TOP4": sortedData[sortedData.length - 4],
"TOP5": sortedData[sortedData.length - 5],
"TOP6": sortedData[sortedData.length - 6],
"TOP7": sortedData[sortedData.length - 7],
"TOP8": sortedData[sortedData.length - 8],
"TOP9": sortedData[sortedData.length - 9],
"TOP10": sortedData[sortedData.length - 10],
"99.9%": sortedData[Math.floor(sortedData.length * 0.999)],
"99%": sortedData[Math.floor(sortedData.length * 0.99)],
"95%": sortedData[Math.floor(sortedData.length * 0.95)],
"90%": sortedData[Math.floor(sortedData.length * 0.90)],
"75%": sortedData[Math.floor(sortedData.length * 0.75)],
"50%": sortedData[Math.floor(sortedData.length * 0.5)],
"25%": sortedData[Math.floor(sortedData.length * 0.25)],
"10%": sortedData[Math.floor(sortedData.length * 0.10)]
};
print(statistic)
_References:
[1]: https://database.guide/2-ways-to-get-a-documents-size-in-mongodb/
[2]: https://stackoverflow.com/questions/22008822/how-to-get-the-size-of-single-document-in-mongodb
[3]: https://www.mongodb.com/docs/v4.2/reference/command/collStats/
[4]: https://database.guide/mongodb-binarysize/
[5]: https://database.guide/mongodb-object-bsonsize/
[6]: https://flowygo.com/en/blog/mongodb-compass-extract-statistics-using-aggregation-pipeline/
[7]: https://www.mongodb.com/docs/manual/aggregation/