在数据库之间复制MongoDb索引

时间:2013-09-27 11:50:50

标签: mongodb indexing

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

这一切都略微超过了顶部所以我认为我必须遗漏一些东西。

有任何建议/良好做法吗?除了有索引创建策略。

干杯!

4 个答案:

答案 0 :(得分:3)

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

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 + ')')
 })});

答案 1 :(得分: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);
    });
});

答案 2 :(得分: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

此致 甲

答案 3 :(得分:1)

这是一个使用选项重新创建它们的版本,以及使用新的createIndex命令而不是ensureIndex(因为mongoDB 3.0)。这样,将所有索引从一个DB复制(重新创建)到另一个DB非常容易。

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({ “子菜单”:1},   { “名”: “submenu_1”, “NS”: “dishly.dishes”, “背景”:真})   db.dishes.createIndex({ “LOC”: “2dsphere”},   { “名称”: “loc_2dsphere”, “NS”: “dishly.dishes”, “2dsphereIndexVersion”:3, “背景”:真})   db.dishes.createIndex({ “RS”: - 1},   { “名”: “RS_-1”, “NS”: “dishly.dishes”, “partialFilterExpression”:{ “RS”:{ “$ GTE”:3}}, “背景”:真})   db.dishes.createIndex({ “LOC”: “2D”, “类型”:1, “状态”:1, “FSID”:1, “RS”: - 1},   { “名称”: “loc_2d_type_1_status_1_rs_-1”, “NS”: “dishly.dishes”, “背景”:真 “partialFilterExpression”:{ “RS”:{ “$ GTE”:2}}})   db.dishes.createIndex({ “_ FTS”: “文本”, “_ ftsx”:1, “loc.0”:1, “loc.1”:1, “RS”: - 1},   { “名”: “d2_menu_submenu_text__loc__rs”, “NS”: “dishly.dishes”, “背景”:真正的 “砝码”:{ “D2”:1, “菜单”:1, “子菜单”:1}” DEFAULT_LANGUAGE “:” 英语”, “language_override”: “语言”, “textIndexVersion”:3})