MongoDB 内のデータの編集方法について (bson ファイルは直接いじれない)

この記事は書かれてから1年以上が経過しており、最新の情報とは異なる可能性があります

crowi (正確には crowi-plus)をローカルで動かしているのですが、 ユーザー名周りや一定の記事のパスを変えたくなってきてしまいました。

で、 crowi で記事部分に使われているデータベースは MongoDB で、 こちらを直接 mongodump, mongorestore コマンドでデータのバックアップなどをとって利用していたのですが、 こちらに吐き出されるファイルは bson (binary json) であるため、 ダンプデータを直接触ることは出来ません。

さてさてどうしましょう、というお話。

方針

mongodump, mongorestore あたりは普通に使っていたのですが、 実際 MongoDB のデータを直接編集する機会が今までなかったので、 どうしたもんかなーという感じであれこれ方針考えました。

  1. bson を json に変換して、編集ののち bson ファイルに戻す
  2. mongodump で json 形式で吐き出してくれる方法がないか?
  3. データベースのビューワーみたいなもので見えるようにしてから GUI 上で編集する
  4. mongodump 以外の方法で json 形式で吐き出す方法はないか?

bson を json に変換する方法

bson と json は等価な情報なので、さくっとググったらすぐ見つかるだろーと思って探してみたら、意外と見つからず。

エディターのプラグインとかで開いたら json で閲覧できる系のもの、あるでしょーと思って見てみても無し。

最悪他に方法がなくとも、変換する方法は何かしらあるだろうと思い、 一旦すぐに見つからなかったのでこの方法は保留に。

mongodump は json 形式では吐き出してくれない

次に mongodump で json で吐き出してくれて、 mongorestore でそれを取り込んでくれれば、 あとは grep とかでどうとでもなると思い、調べてみたものの、 そんなオプションは存在してません。

MongoDB のビューワー

調べてみるといくつかあるようで。

今回は mongo-express というのを使ってみました。

なお、今回 crowi は Dockerized されたものを使っていたので、 同じく Dockerized された mongo-express を利用して、データベースのビューワーを立ち上げました。

https://hub.docker.com/_/mongo-express/

こちらにもあるように、docker run でオプション指定しつつ、すでに動作しているコンテナ名を指定してやれば OK ですね。

docker run --link some_mongo_container:mongo -p 8081:8081 mongo-express

この some_mongo_container がそれですね。 wiki_mongo_1 を指定しつつ、ネットワークのオプション --net wiki_default も併せて指定しています。 (僕の環境では docker network ls でこれが必要だっただけで、他の方の環境はこの限りではありません)

画面の雰囲気知りたい方は、こちらにスクリーンショットがあるので見ると良いかもです。 https://github.com/mongo-express/mongo-express

データベースとコレクションを指定すると、リストのデータがずらっと表示され、 必要な箇所を直接編集することも可能でした。

数が限られているユーザー周りの編集に関しては、これだけで十分事足りたのですが、 記事のパスの編集に関しては、何百というデータ数があり、まあ根性でやれなくもないですが、 エンジニアとして大事な何かを失いそうになるので、この方法は断念することに。

ただ、方法としては使えないものの、どのデータベース、コレクションに修正すべき情報が含まれているかの確認は、 この mongo-express というビューワーで十分行うことが出来ます。

mongodump ではなく、 mongoexport を使う

上記の通りで、どこに修正すべき情報が含まれているかが分かったので、 データベース、コレクション単位でエクスポートが出来る、 mongoexport コマンドを用いることに。

特に今回は Docker を使用しているため、 適当に空ディレクトリと Docker コンテナ内部の /dump を紐づけて、 エクスポートした json ファイルが空ディレクトリに入るようにし、 それを直接編集し、同じように mongoimport コマンドで投入しなおしてます。

結局どの方針が正しいの?

結論としては、この4つ目の mongoexport, mongoimport コマンドを使う、というのが正規の方法と言えそうです。

ただ、どこにどういうデータが入っているのか分からない状態であれば、 一度ビューワーなどを立ち上げて、ざっと閲覧すると理解が早まるかと思います。

手順

今回は以下のような手順で進めて事なきを得ました。

  1. MongoDB が起動している状態にする
  2. mongo-express を起動し、データベースにアクセスしつつ修正箇所を調べる
  3. mongoexport コマンドで、必要なデータベース、コレクションを含む json ファイルをエクスポートする
  4. エディタなどで編集する
  5. mongo-express 上で、エクスポートしたデータを削除しておく
  6. mongoimport コマンドで、修正済みの json ファイルをインポートする

まとめ

mongodump, mongoexport の2種類のコマンドは、単に対象範囲の違いというだけでなくて、 バックアップ用とデータの差し替え用という、用途の違いなんかもあるのかなという印象です。

前者であれば、編集する必要はなくて、全体としてバックアップとりつつ、極力軽い状態にしておきたいので、 bson 形式のファイルでデータ部分を持っておき、 後者であれば、データの差し替えが主な目的だったりするので、 元々 json ファイルでインポート・エクスポートできるようになっていたり、という感じです。

ただ、まあ bson ファイル、エディタで直接編集できる方法があっても良いんじゃないかなあという感じはなくはないです。 (作らないけど)

この記事は書かれてから1年以上が経過しており、最新の情報とは異なる可能性があります

もし記事内に誤りなどございましたら、 @girigiribauer @girigiribauer.com までご一報いただけると助かります。