“For each database” in MongoDB

Published on August 12, 2015 by Kieren

Posted in Technology

Sometimes it’s necessary to perform some administrative or data-management task across different data stores. In SQL Server, there’s sp_MSforeachdb. You can use information_schema to build a dynamic query in MySQL. Here’s an equivalent function for use in MongoDB’s JavaScript interface.

[code lang=”Javascript”]function forEachDb(action, nameFilter) { var m = db.getMongo(); m.getDBs().databases.forEach(function(db) { if (!nameFilter || nameFilter(db.name)) { action(m.getDB(db.name)); } }); } [/code]

This can be pasted either straight into the MongoDB console, or put in: [code lang=”Javascript”]~/.mongorc.js[/code] To be run automatically when the tool is started.

The function is fairly simple – it takes one or two parameters. The first is a function to be run for each database on the current connection; that function should take a single parameter of the database in question. The second parameter is option and specifies a filter function which should return ‘true’ if the database name it is passed should have the action run against it.

For example, to output the number of records in the User collection for each database:

[code lang=”Javascript”]forEachDb(function(d) { print(d.User.count()); }) [/code]

Or to drop any database whose name starts with, the prefix “T_”:

[code lang=”Javascript”]forEachDb(function(d) { d.dropDatabase(); }, function(name) { return name.indexOf(“T_ “) === 0; })[/code]

The last example we use internally to clean up any databases left after some automated integration tests. You could also get aggregated stats in this way:

[code lang=”Javascript”]var total = 0, count = 0; forEachDb(function(d) { total += d.stats().dataSize; count++; }) print((total / 1048576) + ” MB total data across ” + count + ” databases”);[/code]