Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy MongoDb indexes between databases

I am trying to copy mongo indexes between two environments. Checked the API and found no direct method of doing it. So I started writing a script that connects to one db, iterates over the collections, grabs indexes, mutates them (because getIndexes() and ensureIndex()) have different format), connects to the other db, wipes the indexes and copies the new ones in.

This all feels slightly over the top so I think that I must be missing something.

Any suggestions/good practices? Apart from having an index creation strategy.

Cheers!

like image 447
Rince Avatar asked Dec 26 '22 20:12

Rince


2 Answers

Please run it on the database that you want to copy indexes.

db.getCollectionNames().forEach(function(collection) {
indexes = db[collection].getIndexes();
indexes.forEach(function (c) {
opt = ''
ixkey = JSON.stringify(c.key, null, 1).replace(/(\r\n|\n|\r)/gm,"")
ns = c.ns.substr(c.ns.indexOf(".") + 1, c.ns.length)
for (var key in c) {
 if (key != 'key' && key != 'ns' && key != 'v') {
 if (opt != '') { opt+= ','}        
 if (c.hasOwnProperty(key)) {
   if (typeof(c[key]) == "string") {
        opt +=  (key + ': "' + c[key] + '"')
      } else  {
        opt+=  (key + ": " + c[key])
       }
     }
   }
  }
  if (opt != '') { opt = '{' + opt + '}'}
  print ('db.' + ns + '.ensureIndex(' + ixkey + ','+  opt + ')')
 })});
like image 190
Adamo Tonete Avatar answered Jan 18 '23 23:01

Adamo Tonete


I've updated script of Adamo Tonete

db.getCollectionNames().forEach(function(col) {
    var indexes = db[col].getIndexes();
    indexes.forEach(function (c) {
        var fields = '', result = '', options = {};
        for (var i in c) {
            if (i == 'key') {
                fields = c[i];
            } else if (i == 'name' && c[i] == '_id_') {
                return;
            } else if (i != 'name' && i != 'v' && i != 'ns') {
                options[i] = c[i];
            }
        }
        var fields = JSON.stringify(fields);
        var options = JSON.stringify(options);
        if (options == '{}') {
            result = "db." + col + ".createIndex(" + fields + "); ";
        } else {
            result = "db." + col + ".createIndex(" + fields + ", " + options + "); ";
        }
        result = result
            .replace(/{"floatApprox":-1,"top":-1,"bottom":-1}/ig, '-1')
            .replace(/{"floatApprox":(-?\d+)}/ig, '$1')
            .replace(/\{"\$numberLong":"(-?\d+)"\}/ig, '$1');
        print(result);
    });
});
like image 36
lis-dev Avatar answered Jan 19 '23 00:01

lis-dev