getIndexesからcreateIndexを作る

こんにちは。トンペティです。
今日は、mongoDBのインデックスの複製方法とインデックス作成スクリプトの自動生成について話します。

mongoDBのインデックスを別環境にコピーしたい


既存のmongoDB環境のインデックスを複製して、別のmongoDB環境に適用したい!
そこで思いつく方法は二つ。
方法1:バックアップとリストア
mongodumpコマンドでコレクションのバックアップをとり、mongorestoreで別環境にリストア。
ただ、これはコレクションのバックアップなので、インデックスだけじゃなくデータも含んでいます。
データを入れたくないケースでは対応できません。
方法2:インデックス作成メソッドを作成し実行
getIndexesメソッドで既存DBのインデックスを参照し、その内容からcreateIndexメソッドのスクリプトを作成し実行。
複製というか同じものをゼロから構築するイメージですけど、
コレクションのデータを含まないインデックスだけを作るなら、普通はこの方法だと思います。
しかし、既存コレクションからcreateIndexを自動生成するスクリプト生成ウィザードはmongoDBには無く、
地道に1つずつ手作業でcreateIndexのスクリプトを書くしかありません。
当然、インデックスの数が増えると、時間も掛かるし、書き間違いも起こります。
過去には、作成可能なインデックスの上限数となる64個のインデックスを持つコレクションを扱ったこともあり、
そのときはインデックスの全てを作成することは諦めて、い、いつか自動化してやらあ!と思っていましたが...

いつか、、そのうち、、あしたこそ、、? あしたっていつのあしたよ?
やってやります。今こそ、createIndexの自動生成を考えてみましょう。あしたっていまさッ!

getIndexesをcreateIndexに変換する


まず、getIndexesメソッドを実行すると、次のような結果が得られます。

sampledbというデータベースのshopAというコレクションに作られている4つのインデックスが取得できます。

ここで、参考までに、最終的に作りたいcreateIndexメソッドと比較してみましょう。

似て非なるもの。
そこに普遍的な法則を見つけ出してコードに起こすのが自動化の難しいところなのですが、、
ここでそんな苦労話を語る時間は無いので飛ばします。
この世には結果だけが残る!

そうして出来たのが、このcreateIndex自動生成ロジック。

もともとのgetIndexesメソッドをforEachで回しながらcreateIndex向けに変換した内容をprint出力しています。
getIndexes()手前のコレクション名(ここではshopAとしてる部分)を任意に変えれば汎用的に使用可能ッ!

ただ、インデックスのオプションは様々なケースがあるので、すべてのインデックスに対応できているかは、
正直、断言はできませんが、よく使用するオプションは可能な限り試して問題ないことは確認しているので、
大体のインデックスには対応できているはずです。

実行すると次のような結果が得られます。

ちょっと余計な改行が多いのは、printを何回も発行しているため。
printで出力する文字列部分と、printjsononelineで出力する連想配列部分を結合させると、
連想配列部分が”[object BSON]”の文字列に変換されてしまい、どうしても期待する結果が得られなかった...。
そして 一行で出力したいと思ってもできないので、 そのうちトンペティは 考えるのをやめた。

宇宙空間に放り出された絶望感から気持ちを切り替えまして、
改行多めのこのスクリプトは、そのまま使用しても問題なく動作しますが、やはり見栄えを良くしたいので、
最後はサクラエディタを使って調整します。
正規表現の置換を使って、末尾が「;」以外の行の改行を消去オオォォーッ!

置換前 ([^;])\r\n
置換後 $1

これで完成。出来上がったスクリプトを実行すればインデックスは作り放題、複製し放題です!
mongoDB環境構築の際には、一度試してみてください。
インデックスの数がどんなに多くても、もうコピーなんてしないなんて言わないよ絶対。

東京アプリケーションシステム

最近の記事