メインコンテンツへ移動

MongoDB インデックス再構築手順

  1. ストレージコンポーネントのコンテナに入ります。

docker exec -it $(docker ps | grep mingdaoyun-sc | awk '{print $1}') bash

  1. mdwsrowsデータベース配下のユーザー定義インデックスを再構築するため、reIndex.jsスクリプトファイルを作成します。
「reIndex.js」スクリプトファイルの内容
var targetDbName = "mdwsrows"; // 対象データベース
// コレクションホワイトリスト(ホワイトリストに含まれるコレクションは再構築しません)
var collectionWhitelist = [
"discussion",
"rowrelations",
"workSheetRowTopic",
"workSheetTopic",
"wslogs"
];
// インデックスホワイトリスト(ホワイトリストに含まれるインデックスは再構築しません)
var indexWhitelist = [
"_id_",
"idx_ctime",
"idx_utime",
"uk_rowid",
"idx_tp_status",
"idx_thirdprimary"
];
// DateTimeフォーマット関数
function formatDateTime() {
var now = new Date();
var utc8Time = new Date(now.getTime() + (8 * 60 * 60 * 1000));
return utc8Time.toISOString().replace('Z', '+08:00');
}
// 出力フォーマット関数
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}`);
}
// JSONをインデントして出力
function formatJSON(obj, indent = 5) {
return JSON.stringify(obj, null, 2)
.split('\n')
.map((line, i) => i === 0 ? line : ' '.repeat(indent) + line)
.join('\n');
}
// createIndexコマンドのフォーマット
function formatCreateIndexCommand(collName, key, options) {
return `db.${collName}.createIndex(${formatJSON(key)},\n ${formatJSON(options)})`;
}
function printCommand(command) {
print(" └─ 実行:");
print(" " + command);
}
function printCompletion(seconds) {
print(` └─ ✓ ${seconds.toFixed(3)} 秒で完了\n`);
}
// 対象データベースに接続
var targetDb = db.getSiblingDB(targetDbName);
var startTime = formatDateTime();
printHeader("MongoDB インデックス再構築プロセス");
print(`\n• 開始日時: ${startTime}`);
print(`• 対象データベース: ${targetDb.getName()}`);
// ホワイトリストを除外し、再構築対象のコレクション一覧を取得
var collections = targetDb.getCollectionNames().filter(function(collName) {
return !collectionWhitelist.includes(collName) &&
!collName.startsWith('system.');
});
print(`• 対象コレクション数: ${collections.length}`);
collections.forEach(function(collName, index) {
var coll = targetDb.getCollection(collName);
var stats = coll.stats();
// コレクション情報と進捗を出力
printSection(`処理中コレクション [${index + 1}/${collections.length}]: ${collName}`);
print(`\n• ドキュメント件数: ${stats.count}`);
print(`• ストレージサイズ: ${stats.storageSize} バイト`);
// インデックスホワイトリストを除外し、再構築対象インデックスを取得
var indexes = coll.getIndexes();
var rebuildIndexes = indexes.filter(function(idx) {
return !indexWhitelist.includes(idx.name);
});
if (rebuildIndexes.length === 0) {
print("\n✓ 対象インデックスはありません。");
return;
}
// 再構築対象インデックスの出力
print(`\n• 再構築対象インデックス(${rebuildIndexes.length}):`);
rebuildIndexes.forEach(function(idx) {
print(` ├─ 名称: ${idx.name.padEnd(20)}`);
print(` │ キー: ${JSON.stringify(idx.key)}`);
});
// 各インデックスを再構築
rebuildIndexes.forEach(function(idx) {
var key = idx.key;
var options = {};
// システム属性以外の設定をコピー
for (var prop in idx) {
if (!["v", "ns", "background"].includes(prop)) {
options[prop] = idx[prop];
}
}
options.background = true; // バックグラウンドでインデックス作成
try {
// 既存インデックス削除
var dropTime = formatDateTime();
printTimedAction(dropTime, `インデックス削除: ${idx.name}`);
printCommand(`db.${collName}.dropIndex("${idx.name}")`);
var dropStart = new Date();
coll.dropIndex(idx.name);
var dropEnd = new Date();
printCompletion((dropEnd - dropStart)/1000);
// 新規インデックス作成
var createTime = formatDateTime();
printTimedAction(createTime, `インデックス作成: ${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(` └─ ✗ エラー: ${e.message}`);
print(" このインデックスはスキップします...\n");
}
});
});
var endTime = formatDateTime();
printHeader("プロセス完了");
print(`\n• 終了日時: ${endTime}`);
  1. スクリプトを実行します。
nohup mongo mongodb://127.0.0.1:27017/admin --quiet reIndex.js >> reIndex_output.log 2>&1 &
  • 実行ログは reIndex_output.log ファイルに出力されます。
  1. ログを監視し、スクリプト完了まで待機します(Process CompleteとEnd Timeで終了します)。
  2. HAPシステムで依存する一部インデックスを再構築するため、reIndexWithCmd.js スクリプトファイルを作成します。
「reIndexWithCmd.js」スクリプトファイルの内容
// ====================================================================================================
// 設定
// ====================================================================================================
// 対象となるデータベースおよび再構築を除外するコレクションを設定
// 形式: "データベース名": ["除外コレクション1", "除外コレクション2"...]
// 空配列 [] の場合は全コレクションが対象
var targetDatabases = {
"mdpost": [],
"MDHistory": []
};
// ====================================================================================================
// 出力フォーマット関数(変更不要)
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 formatDateTime() {
var now = new Date();
var utc8Time = new Date(now.getTime() + (8 * 60 * 60 * 1000));
return utc8Time.toISOString().replace('Z', '+08:00');
}
function formatJSON(obj, indent = 5) {
if (obj === undefined || obj === null) {
return "Not available";
}
return JSON.stringify(obj, null, 2)
.split('\n')
.map((line, i) => i === 0 ? line : ' '.repeat(indent) + line)
.join('\n');
}
function formatFileSize(bytes) {
if (bytes === undefined || bytes === null) return "N/A";
return (bytes / 1024 / 1024).toFixed(2) + " MB";
}
function printTimedAction(time, action) {
print(`\n[${time}] ${action}`);
}
function printCompletion(seconds) {
print(` └─ ✓ ${seconds.toFixed(3)} 秒で完了\n`);
}
// ====================================================================================================
// スクリプトの実行
// ====================================================================================================
var overallStartTime = formatDateTime();
printHeader("MongoDB 複数データベース インデックス再構築プロセス開始");
print(`\n• 全体開始日時: ${overallStartTime}`);
print(`• 対象データベース: ${Object.keys(targetDatabases).join(', ')}`);
// 各データベースごとに処理
for (var dbName in targetDatabases) {
if (targetDatabases.hasOwnProperty(dbName)) {
printHeader(`データベース処理中: [ ${dbName} ]`);
// 対象DBへ接続
var currentDb = db.getSiblingDB(dbName);
// 現在のデータベースの除外コレクション一覧
var excludedCollections = targetDatabases[dbName];
print(`\n• 対象データベース: ${currentDb.getName()}`);
print(`• 除外コレクション: ${formatJSON(excludedCollections)}`);
// 全コレクション取得
var collections = currentDb.getCollectionNames();
// ブラックリスト・システムコレクション除外
var validCollections = collections.filter(collection =>
!excludedCollections.includes(collection) && !collection.startsWith('system.')
);
print(`• 再構築対象コレクション数: ${validCollections.length}`);
if (validCollections.length === 0) {
print("\n対象コレクションはありません。次のデータベースへ進みます。");
continue;
}
validCollections.forEach(function(collection, index) {
try {
// コレクション統計情報取得
var stats = currentDb[collection].stats();
// コレクション情報・進捗を出力
printSection(`処理中コレクション [${index + 1}/${validCollections.length}]: ${collection}`);
print(`\n• コレクション統計情報:`);
print(` ├─ ストレージサイズ: ${formatFileSize(stats.storageSize)}`);
print(` └─ ドキュメント数: ${(stats.count || 0).toLocaleString()}`);
// インデックス情報取得
var indexes = currentDb[collection].getIndexes();
print(`\n• 現在のインデックス(${indexes.length}):`);
indexes.forEach(function(idx, i) {
const isLast = i === indexes.length - 1;
print(` ${isLast ? '└' : '├'}─ 名称: ${idx.name.padEnd(20)}`);
print(` ${isLast ? ' ' : '│'} キー: ${formatJSON(idx.key)}`);
});
// reIndex実行
var execTime = formatDateTime();
printTimedAction(execTime, "reIndex()を実行");
print(" └─ 実行:");
print(` db.getSiblingDB('${dbName}').getCollection('${collection}').reIndex()`);
var startExec = new Date();
var result = currentDb[collection].reIndex();
var endExec = new Date();
if (result.ok === 1) {
printCompletion((endExec - startExec)/1000);
print("• 実行結果:");
print(` ├─ 前回インデックス数: ${result.nIndexesWas}`);
print(` ├─ 現在インデックス数: ${result.nIndexes}`);
if (result.operationTime !== undefined) {
print(` ├─ Operation Time: ${formatJSON(result.operationTime)}`);
} else {
print(` ├─ Operation Time: 非レプリカセット環境のため取得不可`);
}
if (result.$clusterTime !== undefined) {
print(` └─ Cluster Time: ${formatJSON(result.$clusterTime)}`);
} else {
print(` └─ Cluster Time: 非レプリカセット環境のため取得不可`);
}
} else {
print(` └─ ✗ ReIndex失敗: ${formatJSON(result)}`);
}
} catch (e) {
print(` └─ ✗ エラー: ${e.message}`);
print(" このコレクションはスキップします...\n");
}
});
}
}
var overallEndTime = formatDateTime();
printHeader("プロセス完了");
print(`\n• 全体終了日時: ${overallEndTime}`);
  1. スクリプトを実行します。
nohup mongo mongodb://127.0.0.1:27017/admin --quiet reIndexWithCmd.js >> reIndexWithCmd_output.log 2>&1 &
  • 実行ログは reIndexWithCmd_output.log ファイルに出力されます。
  1. ログを監視し、スクリプト完了まで待機します(ログ末尾に Process Complete および End Time と出力されます)。