MongoDB如何将索引定义从一个集合复制到另一个集合?

时间:2017-03-31 21:52:55

标签: mongodb

我知道有办法做db.collection.getIndexes()这将列出为集合定义的所有索引。有没有办法将这些索引定义复制并创建到另一个集合?

有很多这些,我不想一个接一个地做。

关于重复的问题评论:我不想复制一个集合。我希望以我可以应用于另一个集合的格式导出索引。

5 个答案:

答案 0 :(得分:9)

例如,我有一个现有的用户集合,其索引为 _id _ name_1 email_1 WEBSITE_1

然后我有另一个名为 usertest 的集合,我想将用户集合中的索引复制到 usertest 集合。以下命令适用于此方案:

  1. 复制索引键和索引选项

    var indexes = db.user.getIndexes();
    
    indexes.forEach(function(index){
        delete index.v;
        delete index.ns;
    
        var options = [];
        for (var option in index) {
            if (option != 'key') {
                options.push(index['option']);
            }
        }
       db.usertest.createIndex(index.key, options);
    });
    
  2. 仅复制索引键(批处理)

    var indexKeys = db.user.getIndexKeys();
    db.usertest.createIndexes(indexKeys);
    
  3. 希望这会有所帮助。这是文档:createIndexes

答案 1 :(得分:0)

感谢Rocky and Bloke的回答,这对我有很大帮助 这是Bloke建议的合并版本。 并在生产中。我们要确保背景:true 复制索引创建时,用于避免从站暂停查询。

var indexes = db.user.getIndexes();
// we skipped the __id__ indexes and set the default background: true option
indexes.forEach(function(index){
    if(index.name =='_id_'){
     print("we are skip the _id_ index")
    }else{
    delete index.v;
    delete index.ns;
    var key = index.key;
    delete index.key
    var options = {};
    for (var option in index) {
        options[option] = index[option]
    }
    options['background'] = true;
    printjson(key);
    printjson(options);
    db.usertest.createIndex(key, options);

   }
});

答案 2 :(得分:0)

Rocky Li的回答很有帮助,但在撰写本文时未正确创建索引选项(它收集了选项值而不是键)。以下修改对我有用:

var indexes = db.user.getIndexes();

indexes.forEach(function(index){
    delete index.v;
    delete index.ns;
    var key = index.key;
    delete index.key

    // uncomment if you want to ensure creation is in background
    //if(!('background' in index))
        //index['background'] = true;

   db.user.createIndex(key, index);
});

答案 3 :(得分:0)

将所有索引从一个数据库复制到另一个数据库

 use firstDbName;
 var indexKeyArray = [];
 db.getCollectionNames().forEach(function(collection) {
 var indexKeys = db[collection].getIndexKeys();
 var base = {};
 base["name"] = collection;
 base["indices"] = indexKeys
 indexKeyArray.push(base);
});
#printjson(indexKeyArray);
use destinationDbName;
indexKeyArray.forEach(function(data) {
  db[data.name].createIndexes(data.indices);
});

答案 4 :(得分:0)

要直接在 MongoDB 中执行此操作,请执行以下操作,

以下命令将为所有集合的现有索引生成 mongo DB 查询,

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

以上命令将根据您拥有的收藏数量输出如下内容

db.User.createIndex({"createdAt":-1}, {"background":true}); 

db.User.createIndex({"updatedAt":-1}, {"background":true}); 

db.Login.createIndex({"loginDate":-1}, {"background":true}); 

因此,执行此操作后,将上面生成的用于创建索引的 MongoDB 查询复制到新集合中,更改其中的集合名称,然后执行它。

例如:要将属于 User 集合的所有索引复制到 UserNew 集合,我将查询的旧集合名称重命名为 new 如下所示并执行它,就是这样,现在您已将所有索引复制到旧收藏的新收藏。

db.UserNew.createIndex({"createdAt":-1}, {"background":true}); 

db.UserNew.createIndex({"updatedAt":-1}, {"background":true}); 

信用:http://aleksandrmaiorov.com/2019/04/29/mongo-how-to-copy-indexes-from-one-database-to-another/