Skip to content

Instantly share code, notes, and snippets.

@joeyAghion
Last active February 9, 2024 22:37
Show Gist options
  • Save joeyAghion/6511184 to your computer and use it in GitHub Desktop.
Save joeyAghion/6511184 to your computer and use it in GitHub Desktop.
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'] + ")"); }
@msplival
Copy link

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
Copy link

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
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,

@snehansu-bhusan
Copy link

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
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
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
Copy link

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

@vishal3152
Copy link

vishal3152 commented Sep 23, 2020

Try this to get all DBs, collections and document count:

mongo --eval " db.getMongo().getDBNames().forEach( function(v, i){ db.getSiblingDB(v).getCollectionNames().forEach( function(vv, ii){ print (v + ',' + vv + ',' + db.getSiblingDB(v).getCollection(vv).count() ) } ) } ) "

@nenohweg
Copy link

nenohweg commented Jan 4, 2024

Is there a way to then store this data in a collection as historical data . To monitor collection size growth over a period of time

@dwinrick-lever
Copy link

@nenohweg something like datadog?

Also here's a version which works better for me - the versions at the top of this thread *** will silently omit values as they error on system.profile ***

(function() {
  const byteUnits = [" kB", " MB", " GB", " TB", "PB", "EB", "ZB", "YB"];

  // get collections by size sorted
  function getReadableFileSizeString(fileSizeInBytes) {
    let i = -1;
    do {
      fileSizeInBytes = fileSizeInBytes / 1024;
      i++;
    } while (fileSizeInBytes > 1024);

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

  const collectionNames = db.getCollectionNames();
  let stats = [];
  for (const name of collectionNames) {
    if (name === 'system.profile') {
      continue;
    }
    stats.push(db.getCollection(name).stats());
  }
  stats = stats.sort(function(a, b) {
    return b["size"] - a["size"];
  });
  for (let i = 0; i < stats.length; i++) {
    console.log(stats[i]["ns"] + ": " + getReadableFileSizeString(stats[i]["size"]) + " (" + getReadableFileSizeString(stats[i]["storageSize"]) + ") - ", Number(stats[i].count).toLocaleString(), " docs");
  }
})();

Also includes formatted doc count.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment