Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
List mongodb collections in descending order of size. Helpful for finding largest collections. First number is "size," second is "storageSize."
var collectionNames = db.getCollectionNames(), stats = [];
collectionNames.forEach(function (n) { stats.push(db[n].stats()); });
stats = stats.sort(function(a, b) { return b['size'] - a['size']; });
for (var c in stats) { print(stats[c]['ns'] + ": " + stats[c]['size'] + " (" + stats[c]['storageSize'] + ")"); }
@MWers

This comment has been minimized.

Copy link

MWers commented Nov 25, 2015

Nice gist, thanks! I tweaked it slightly using a human-readable storage size function from StackOverflow:

function getReadableFileSizeString(fileSizeInBytes) {

    var i = -1;
    var byteUnits = [' kB', ' MB', ' GB', ' TB', 'PB', 'EB', 'ZB', 'YB'];
    do {
        fileSizeInBytes = fileSizeInBytes / 1024;
        i++;
    } while (fileSizeInBytes > 1024);

    return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];
};
var collectionNames = db.getCollectionNames(), stats = [];
collectionNames.forEach(function (n) { stats.push(db[n].stats()); });
stats = stats.sort(function(a, b) { return b['size'] - a['size']; });
for (var c in stats) { print(stats[c]['ns'] + ": " + getReadableFileSizeString(stats[c]['size']) + " (" + getReadableFileSizeString(stats[c]['storageSize']) + ")"); }
@lattmann

This comment has been minimized.

Copy link

lattmann commented Dec 8, 2015

Improved how to get the collection:

function getReadableFileSizeString(fileSizeInBytes) {

    var i = -1;
    var byteUnits = [' kB', ' MB', ' GB', ' TB', 'PB', 'EB', 'ZB', 'YB'];
    do {
        fileSizeInBytes = fileSizeInBytes / 1024;
        i++;
    } while (fileSizeInBytes > 1024);

    return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];
};
var collectionNames = db.getCollectionNames(), stats = [];
collectionNames.forEach(function (n) { stats.push(db.getCollection(n).stats()); });
stats = stats.sort(function(a, b) { return b['size'] - a['size']; });
for (var c in stats) { print(stats[c]['ns'] + ": " + getReadableFileSizeString(stats[c]['size']) + " (" + getReadableFileSizeString(stats[c]['storageSize']) + ")"); }
@levay1

This comment has been minimized.

Copy link

levay1 commented Aug 22, 2016

Hi Guys,

This script really helps, thanks a lot. I'm a mongodb DBA; pretty new to java script. Can you suggest me something to improve my java-script skills (Especially for mongoDB). I need to write my own scripts like this. Also can you explain me the above script, how it works? Thanks for a lot

Regards
Albert

@marzsv

This comment has been minimized.

Copy link

marzsv commented Dec 2, 2016

Hi @levay1, the script provided by lattmann does the following:

  • Defines a function called "getReadableFileSizeString" that converts a number of bytes to a more human readable string.
  • Then gest all collection names in "collectionNames" variable.
  • Get the stats for all collections and stores them in the array variable "stats"
  • Sorts the stats by size
  • Finally traverse all the stats and prints the Namespace and both sizes (size and storageSize)

If you would like to improve your javascript skills, there are tons of material, here are a few:

@RichardBronosky

This comment has been minimized.

Copy link

RichardBronosky commented Jan 11, 2017

I took @lattmann's human readable version and made a loop of all the databases.

var mgo = new Mongo()

function getReadableFileSizeString(fileSizeInBytes) {

    var i = -1;
    var byteUnits = [' kB', ' MB', ' GB', ' TB', 'PB', 'EB', 'ZB', 'YB'];
    do {
        fileSizeInBytes = fileSizeInBytes / 1024;
        i++;
    } while (fileSizeInBytes > 1024);

    return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];
};

function getStatsFor(db){
    var collectionNames = db.getCollectionNames(), stats = [];
    collectionNames.forEach(function (n) { stats.push(db.getCollection(n).stats()); });
    stats = stats.sort(function(a, b) { return b['size'] - a['size']; });
    for (var c in stats) { print(stats[c]['ns'] + ": " + getReadableFileSizeString(stats[c]['size']) + " (" + getReadableFileSizeString(stats[c]['storageSize']) + ")"); }
}

function getAllStats(){
    mgo.getDBNames().forEach(function(name){ var db = mgo.getDB(name); print('\n    '+db+'\n'); getStatsFor(db) })
}

getAllStats()

With these functions you can get stats for the current (use) DB with a simple getStatsFor(db) call, or get stats for a named DB with getStatsFor(mgo.getDB('db_name'))

@msplival

This comment has been minimized.

Copy link

msplival commented Jul 26, 2017

This will actually fail if mongo is not running on 27017, or if it's configured to use SSL, and so on.

The first line should be changed like this:

var mgo = db.getMongo()

@yoshikakbudto

This comment has been minimized.

Copy link

yoshikakbudto commented Sep 14, 2018

reworked abit @RichardBronosky 's code to include indexes stats

var mgo = new Mongo()

function getReadableFileSizeString(fileSizeInBytes) {

    var i = -1;
    var byteUnits = [' kB', ' MB', ' GB', ' TB', 'PB', 'EB', 'ZB', 'YB'];
    do {
        fileSizeInBytes = fileSizeInBytes / 1024;
        i++;
    } while (fileSizeInBytes > 1024);

    return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];
};

function getStatsFor(db){
    var collectionNames = db.getCollectionNames(), stats = [];
    collectionNames.forEach(function (n) { stats.push(db.getCollection(n).stats()); });
    stats = stats.sort(function(a, b) { return b['size'] - a['size']; });
    for (var c in stats) { 
        print(stats[c]['ns'] + ": " + getReadableFileSizeString(stats[c]['size']) + " (" + getReadableFileSizeString(stats[c]['storageSize']) + ")");
        for (var i in stats[c]['indexSizes']){ print("  idx:" + i + ":" + getReadableFileSizeString(stats[c]['indexSizes'][i]) );}
    }
}



function getAllStats(){
    mgo.getDBNames().forEach(function(name){ var db = mgo.getDB(name); print('\n    '+db+'\n'); getStatsFor(db) })
}

getAllStats()

@nifira04

This comment has been minimized.

Copy link

nifira04 commented Oct 2, 2018

Wanna ask something, how to use this script with authentication enable. because i got error message like this:

"errmsg" : "not authorized on admin to execute command { listDatabases: 1.0, $db: \"admin\" }",

Thank you,

@sneh-misra

This comment has been minimized.

Copy link

sneh-misra commented Oct 28, 2018

More readable including index and collection document counts

var mgo = new Mongo()
function getReadableFileSizeString(fileSizeInBytes) {
    var i = -1;
    var byteUnits = [' kB', ' MB', ' GB', ' TB', 'PB', 'EB', 'ZB', 'YB'];
    do {
        fileSizeInBytes = fileSizeInBytes / 1024;
        i++;
    } while (fileSizeInBytes > 1024);
    return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];
};
function getStatsFor(db){
    var collectionNames = db.getCollectionNames(), stats = [];
    collectionNames.forEach(function (n) { stats.push(db.getCollection(n).stats());});
    stats = stats.sort(function(a, b) { return b['size'] - a['size']; });
    for (var c in stats) { 
        print(
        "collectionName" +":"+ stats[c]['ns'] +"-"+ 
        "documentCount" +":"+ stats[c]['count'] +"-"+ 
        "indexesCount" +":"+ stats[c]['nindexes'] +"-"+ 
        "totalIndexSize" +":"+ getReadableFileSizeString(stats[c]['totalIndexSize']) +"-"+ 
        "size" +":"+ getReadableFileSizeString(stats[c]['size']) +"-"+
        "storageSize" +":"+ getReadableFileSizeString(stats[c]['storageSize']) );
        for (var i in stats[c]['indexSizes']){ print("  idx:" + i + ":" + getReadableFileSizeString(stats[c]['indexSizes'][i]) );}
    }
}
function getAllStats(){
    mgo.getDBNames().forEach(function(name){ var db = mgo.getDB(name); print('\n    '+db+'\n'); getStatsFor(db) })
}
getAllStats()
@guyarad

This comment has been minimized.

Copy link

guyarad commented Jan 10, 2019

thanks for this awesome script and the updates!

I have incorporated most of the above, added output customizations (include/exclude index, sorting order, long/short format)
feel free to check it out my gist

EDIT: added small improvement to getReadableFileSizeString. It now accepts number of decimal places, and truncate extra zeros from the number (just by casting to a Number before printing).

@terrywh

This comment has been minimized.

Copy link

terrywh commented Dec 1, 2019

You can write a more 'elegant' version:

function getCollectionSizes() {
    db.getCollectionNames().map(function(name) {
        return {"name":name, "size": db.getCollection(name).stats()["size"] || 0};
    }).sort(function(a, b) {
        return b["size"] - a["size"];
    }).forEach(function(x) {
        // MongoDB JavaScript Engine does not support string.padEnd
        let pad = "                ";
        print(x.name + pad.slice(0, Math.max(16 - x.name.length, 0)) + ":\t" + x.size);
    });
}
getCollectionSizes();
@terencehonles

This comment has been minimized.

Copy link

terencehonles commented Apr 27, 2020

If you're using a newer version of mongo which supports ES6 this is a more terse form of the above with information about the index sizes and uses 3 decimal places like show dbs does from the mongo shell

const readableSize = (size) => {                                               
  const scale = (Math.log(size) / Math.log(1024)) | 0;                         
  return (size / Math.pow(1024, scale)).toFixed(3) + ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'][scale];
}                                                                              
                                                                               
const printStats = (mongo) => {                                                
  mongo.getDBNames()                                                           
    .map((i) => mongo.getDB(i))                                                
    .forEach((db) => {                                                         
      print(db);                                                               
      print(Array(81).join('='));                                              
      db.getCollectionNames()                                                  
        .map((i) => db.getCollection(i).stats())                               
        .sort((a, b) => b.size - a.size)                                       
        .forEach((s) => {                                                      
          print(`${s.ns}: ${readableSize(s.size)} (${readableSize(s.storageSize)})`);
          print(`Indexes: (${readableSize(s.totalIndexSize)})`);               
          Object.entries({...s.indexSizes}).sort((a, b) => b[1] - a[1]).forEach(([n, s]) => {
            print(`  ${n}: ${readableSize(s)}`);                               
          });                                                                  
          print('');                                                           
        });                                                                    
                                                                               
      print('');                                                               
    });                                                                        
}                                                                              

// and used:                                                                               
printStats(db.getMongo())                                                      

which would render:

admin
================================================================================
admin.system.users: 4.284kB (36.000kB)
Indexes: (72.000kB)
  _id_: 36.000kB
  user_1_db_1: 36.000kB

admin.system.keys: 425.000B (36.000kB)
Indexes: (36.000kB)
  _id_: 36.000kB

admin.system.version: 104.000B (36.000kB)
Indexes: (32.000kB)
  _id_: 32.000kB


config
================================================================================
config.system.sessions: 41.995MB (9.809MB)
Indexes: (38.055MB)
  _id_: 36.574MB
  lsidTTLIndex: 1.480MB

config.transactions: 304.604kB (204.000kB)
Indexes: (1.250MB)
  _id_: 1.250MB
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.