Skip to main content

MongoDB Index Rebuild

  1. Enter the storage component container

    docker exec -it $(docker ps | grep mingdaoyun-sc | awk '{print $1}') bash
  1. Create the reIndex.js script file

    Script file content for reIndex.js, the script defaults to the mdwsrows database
    var targetDbName = "mdwsrows";  // Target database

    // Collection whitelist, indexes in whitelisted collections are not rebuilt
    var collectionWhitelist = [
    "discussion",
    "rowrelations",
    "workSheetRowTopic",
    "workSheetTopic",
    "wslogs"
    ];

    // Index whitelist, whitelisted indexes are not rebuilt
    var indexWhitelist = [
    "_id_",
    "idx_ctime",
    "idx_utime",
    "uk_rowid",
    "idx_tp_status",
    "idx_thirdprimary"
    ];

    // Function to format time
    function formatDateTime() {
    var now = new Date();
    var utc8Time = new Date(now.getTime() + (8 * 60 * 60 * 1000));
    return utc8Time.toISOString().replace('Z', '+08:00');
    }

    // Function to format output
    function printHeader(text) {
    print("\n" + "=".repeat(100));
    print(text);
    print("=".repeat(100));
    }

    function printSection(text) {
    print("\n" + "-".repeat(80));
    print(text);
    print("-".repeat(80));
    }

    function printTimedAction(time, action) {
    print(`\n[${time}] ${action}`);
    }

    // Function to format JSON, consistent indentation
    function formatJSON(obj, indent = 5) {
    return JSON.stringify(obj, null, 2)
    .split('\n')
    .map((line, i) => i === 0 ? line : ' '.repeat(indent) + line)
    .join('\n');
    }

    // Function to format createIndex command
    function formatCreateIndexCommand(collName, key, options) {
    return `db.${collName}.createIndex(${formatJSON(key)},\n ${formatJSON(options)})`;
    }

    function printCommand(command) {
    print(" └─ Execute:");
    print(" " + command);
    }

    function printCompletion(seconds) {
    print(` └─ ✓ Completed in ${seconds.toFixed(3)} seconds\n`);
    }

    // Connect to specified database
    var targetDb = db.getSiblingDB(targetDbName);
    var startTime = formatDateTime();

    printHeader("MongoDB Index Rebuild Process");
    print(`\n• Start Time: ${startTime}`);
    print(`• Target Database: ${targetDb.getName()}`);

    // Get all collections to rebuild, filtering out whitelist collections
    var collections = targetDb.getCollectionNames().filter(function(collName) {
    return !collectionWhitelist.includes(collName) &&
    !collName.startsWith('system.');
    });

    print(`• Total Collections: ${collections.length}`);

    collections.forEach(function(collName, index) {
    var coll = targetDb.getCollection(collName);
    var stats = coll.stats();

    // Output collection information and progress
    printSection(`Processing Collection [${index + 1}/${collections.length}]: ${collName}`);
    print(`\n• Document Count: ${stats.count}`);
    print(`• Storage Size: ${stats.storageSize} bytes`);

    // Get indexes to rebuild, filtering out whitelist indexes
    var indexes = coll.getIndexes();
    var rebuildIndexes = indexes.filter(function(idx) {
    return !indexWhitelist.includes(idx.name);
    });

    if (rebuildIndexes.length === 0) {
    print("\n✓ No indexes need to be rebuilt.");
    return;
    }

    // Output index rebuild plan
    print(`\n• Indexes to Rebuild (${rebuildIndexes.length}):`);
    rebuildIndexes.forEach(function(idx) {
    print(` ├─ Name: ${idx.name.padEnd(20)}`);
    print(` │ Key: ${JSON.stringify(idx.key)}`);
    });

    // Rebuild each index
    rebuildIndexes.forEach(function(idx) {
    var key = idx.key;
    var options = {};

    // Copy index configuration, excluding system attributes
    for (var prop in idx) {
    if (!["v", "ns", "background"].includes(prop)) {
    options[prop] = idx[prop];
    }
    }
    options.background = true; // Build index in the background

    try {
    // Drop old index
    var dropTime = formatDateTime();
    printTimedAction(dropTime, `Dropping Index: ${idx.name}`);
    printCommand(`db.${collName}.dropIndex("${idx.name}")`);

    var dropStart = new Date();
    coll.dropIndex(idx.name);
    var dropEnd = new Date();
    printCompletion((dropEnd - dropStart)/1000);

    // Create new index
    var createTime = formatDateTime();
    printTimedAction(createTime, `Creating Index: ${idx.name}`);
    printCommand(formatCreateIndexCommand(collName, key, options));

    var createStart = new Date();
    coll.createIndex(key, options);
    var createEnd = new Date();
    printCompletion((createEnd - createStart)/1000);

    } catch (e) {
    print(` └─ ✗ Error: ${e.message}`);
    print(" Skipping this index...\n");
    }
    });
    });

    var endTime = formatDateTime();
    printHeader("Process Completed");
    print(`\n• End Time: ${endTime}`);
  1. Execute the script

    nohup mongo mongodb://127.0.0.1:27017/admin --quiet reIndex.js >> reIndex_output.log 2>&1 &
    • The execution log will be output to the reIndex_output.log file
  1. Monitor the log and wait for the script to complete (the end of the log will output Process Complete and End Time)