4

我正在尝试在两个环境之间复制 mongo 索引。检查API,发现没有直接的方法。所以我开始编写一个脚本,它连接到一个数据库,遍历集合,抓取索引,改变它们(因为getIndexes()ensureIndex())具有不同的格式),连接到另一个数据库,擦除索引并复制新的索引。

这一切都感觉有点过头了,所以我认为我一定错过了一些东西。

有什么建议/好的做法吗?除了有一个索引创建策略。

干杯!

4

4 回答 4

6

请在要复制索引的数据库上运行它。

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 + ')')
 })});
于 2015-11-28T20:15:55.190 回答
3

我更新了 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);
    });
});
于 2017-07-11T13:49:44.233 回答
1

试试这个脚本:

var i, c, 
    co_name, co_new, 
    co_old, co_old_i, 
    _db = db.getSiblingDB('logs'), 
    _colls = ['activity.games', 'activity.session', 'activity.social', 'activity.store'];

for (i in _colls){
    co_name = _colls[i];
    co_old = _db[co_name];
    co_old_i = co_old.getIndexes();
    if(co_old.count() > 0){
        co_old.renameCollection(co_name + '.old');
        _db.createCollection(co_name);  
        co_new = _db[co_name];
        for(c in co_old_i){
            co_new.ensureIndex(co_old_i[c].key);
        }   
    }
}

https://gist.github.com/alejandrobernardis/8261327

问候,

于 2014-01-04T22:27:51.050 回答
1

这是一个使用选项重新创建它们的版本,并且使用新的 createIndex 命令而不是 ensureIndex(从 mongoDB 3.0 开始)。这样,将所有索引从一个数据库复制(重新创建)到另一个数据库非常容易。

function createIndex2( coll, keys, options ) {
    var ret = db[coll].createIndex(keys, options)
    if (ret.createdCollectionAutomatically) print( "Collection " + coll + " was created")
    if (ret.errmsg || (ret.note != "all indexes already exist" && ret.ok != 1)) {
      ret.coll = coll
      ret.keys = keys
      ret.options = options
      print(tojson(ret))      
    } else {
        //print( "Everything normal", JSON.stringify(ret)) 
    }
}

db.getCollectionInfos().forEach(function(coll) {
  //print( JSON.stringify( coll ))
  if (coll.type === "collection" ) {
    db[coll.name].getIndexes().forEach(function(index) {
        if ("_id_" !== index.name) {
            //print( JSON.stringify( index ))
            var indexKey = index.key        // save the key, and transform index into the "options"
            delete index.key
            delete index.ns     // namespace - not necessary
            delete index.v      // not necessary
            index.background = true     // optional: force background to be true
            //native version: print("db." + coll.name + ".createIndex(" + JSON.stringify(indexKey) + ", " + JSON.stringify(index) + ")");
            // this gives much more debug info
            print("createIndex2(\"" + coll.name + "\", " + JSON.stringify(indexKey) + ", " + JSON.stringify(index) + ")");
            }
    });
  }
});

如果使用“本机”版本,结果看起来像这样,否则,它将只显示错误:

db.dishes.createIndex({"submenu":1}, {"name":"submenu_1","ns":"dishly.dishes","background":true}) db.dishes.createIndex({"loc" :"2dsphere"}, {"name":"loc_2dsphere","ns":"dishly.disshes","2dsphereIndexVersion":3,"background":true}) db.dishes.createIndex({"rs":- 1}, {"name":"rs_-1","ns":"dishly.dishes","partialFilterExpression":{"rs":{"$gte":3}},"background":true}) db.dishes.createIndex({"loc":"2d","type":1,"status":1,"FSid":1,"rs":-1}, {"name":"loc_2d_type_1_status_1_rs_-1 ","ns":"dishly.dishes","背景":true,"partialFilterExpression":{"rs":{"$gte":2}}}) db.dishes.createIndex({"_fts":"text","_ftsx":1,"loc.0 ":1,"loc.1":1,"rs":-1}, {"name":"d2_menu_submenu_text__loc__rs","ns":"dishly.dishes","background":true,"weights":{ "d2":1,"menu":1,"submenu":1},"default_language":"english","language_override":"language","textIndexVersion":3})d2_menu_submenu_text__loc__rs","ns":"dishly.disshes","background":true,"weights":{"d2":1,"menu":1,"submenu":1},"default_language":"english" ,"language_override":"language","textIndexVersion":3})d2_menu_submenu_text__loc__rs","ns":"dishly.disshes","background":true,"weights":{"d2":1,"menu":1,"submenu":1},"default_language":"english" ,"language_override":"language","textIndexVersion":3})

于 2018-05-21T20:29:48.787 回答