mongodb how to mongodump only indexes to another mongodb instance
Asked Answered
A

4

15

I have a mongodb instance with a lot of data, now I need to start up a new instance with the same structure without data.

how to get it done?

Aviation answered 20/10, 2014 at 4:8 Comment(0)
K
18

You can do that with the "query" option, with a query that does not return any document. Something like:

mongodump -q '{ "foo" : "bar"  }'

This will dump all the dbs and indexes, you can then do a mongorestore to recreate them into another mongod instance

See documentation: http://docs.mongodb.org/manual/reference/program/mongodump/#cmdoption--query

Kassia answered 20/10, 2014 at 6:0 Comment(3)
Good trick. However if you do have a big collection without "foo" indexed, it will be very slow. The workaround is using _id which always has index: mongodump -q '{ "_id" : "bar" }'Sixtyfourmo
Well may I raise this ironic - here we discuss about why mongnodb NOT restore index when mongorestore ref. https://mcmap.net/q/606127/-why-mongodump-does-not-backup-indexesHydrostatic
As of version 3.6.3, this trick doesn't quite work. I get bad option: cannot dump using a query without a specified collection. It works if I specify the collection - but of course this means that I have to know all the collections before I start.Abampere
P
9

You can login into mongo shell and execute the following code statements to generate creating indexes statements. After that, use the statements to recreate indexes.

var collectionList = db.getCollectionNames();
for(var index in collectionList){
    var collection = collectionList[index];
        var cur = db.getCollection(collection).getIndexes();
        if(cur.length == 1){
            continue;
        }
        for(var index1 in cur){
            var next = cur[index1];
            if(next["name"] == '_id_'){
                continue;
            }
       var unique=next["unique"]?true:false;
       print("try{ db.getCollection(\""+collection+"\").createIndex("+JSON.stringify(next["key"])+",{unique:"+unique+"},{background:1})}catch(e){print(e)}");}}
Pick answered 31/8, 2019 at 9:57 Comment(1)
If I could give you +1 ten extra times on this I would. Nice little script.Achaemenid
E
7

There is really short and briliant script for create backup of indexes queries:

print(`// Backup indexes of : ${db.getName()} : database`);
print(`use ${db.getName()};`);

db.getCollectionNames().forEach(function (collection) {
    indexes = db.getCollection(collection).getIndexes().forEach(function (index) {
        if (index.name === '_id_') return; // skip defalut _id indexes
        const keys = tojsononeline(index.key);
        delete index.id; delete index.key; delete index.v; delete index.ns;
        print(`db.${collection}.createIndex(${keys}, ${tojsononeline(index)});`);
    });
});

You can run it directly from mongo shell like this:

mongo --quiet mongodb://localhost:27017/mydatabase indexes-backup.js

Output looks like:

db.user.createIndex({"user.email":1}, {"name":"userEmail", "background":true});
Embarkment answered 22/4, 2020 at 9:35 Comment(0)
L
1

Based on Ivan's answer, I improved the script by adding more options like expireAfterSeconds (which was crucial for me) and an flag variable to drop indexes before creating them. dropFirst variable at the top of the script can be set to true to drop every index before creating it. Also, this script keeps existing names of the indexes.

var dropFirst = false;

for(var collection of db.getCollectionNames()) {
    var indexes = db.getCollection(collection).getIndexes().filter(i => i.name !== '_id_');
    if(indexes.length === 0) continue;
    print(`\n// Collection: ${collection}`);
    for(var index of indexes) {
        var key = JSON.stringify(index.key);
        var opts = [`name: "${index.name}"`, 'background: true'];
        if(index['unique']) opts.push('unique: true');
        if(index['hidden']) opts.push('hidden: true');
        if(index['sparse']) opts.push('sparse: true');
        if(index['expireAfterSeconds'] !== undefined) opts.push(`expireAfterSeconds: ${index['expireAfterSeconds']}`);
        if(dropFirst) {
            print(`try { db.getCollection("${collection}").dropIndex(${key}); } catch(e) { print('failed to drop ${key}:', e); }`);
        }
        print(`try { db.getCollection("${collection}").createIndex(${key}, {${opts.join(', ')}}) } catch(e) { print('failed to create ${key}:', e) }`);
    }
}

Leven answered 5/2, 2021 at 11:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.