0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MongoDBのデータベース/コレクション/インデックスの一覧をCSV/PlantUMLで表示する

Posted at

やりたいこと

MongoDBを使った開発を行ってきたが現物とドキュメントとの乖離が出てきたり、他人が設計したものの面倒を見ることになってしまうことが出てきた。なので現物からデータベース/コレクション/インデックスを抜き出し視覚化して概要を把握したい・ドキュメント化したい。

RDBMSでER図を作成するSchemaSpyみたいなことをしたい感じ。

結果としての出力は

  • テキストでツリー形式
  • CSV形式(Excelで読んだり…)
  • PlantUML

が選べる様にしたい。

方法

MongoDBは内部でJavaScriptを実行できるので、これでデータベース一覧→コレクション一覧→インデックスの順で順次取得するスクリプトを書いた。

MongoDBでJavaScriptはこんな感じで実行できる。

$ mongosh mongodb://server:port -f script.js

できたもの

コメント入れて100行以下なので貼っておく。

getMongoCollections.js
// 出力フォーマットを得る
const format = process.env.FORMAT || 'text';

// ヘッダー出力
if (format === 'csv') {
  print('Database,Collection,Index');
} else if (format === 'plantuml') {
  print('@startuml');
  print('left to right direction');
  print('scale 300 width');
}

// データベース一覧を取得
const databases = db.adminCommand('listDatabases').databases;

// データベースをそれぞれ調べる
databases.forEach(database => {
  const dbName = database.name;

  // システムデータベースは無視する
  if (dbName === 'admin' || dbName === 'config' || dbName === 'local') {
    return;
  }

  // データベース名を表示
  if (format === 'csv') {
    print(`${dbName},,`);
  } else if (format === 'plantuml') {
    print(`database ${dbName} {`);
  } else {
    print(`Database: ${dbName}`);
  }

  // データベースを切り替え
  const currentDb = db.getSiblingDB(dbName);

  // コレクション一覧を取得
  const collections = currentDb.getCollectionNames();

  // コレクションを調べる
  collections.forEach(collection => {

    // コレクション名を表示
    if (format === 'csv') {
      print(`,${collection},`);
    } else if (format === 'plantuml') {
      print(`  folder ${collection} {`);
    } else {
      print(`  Collection: ${collection}`);
    }

    // インデックス一覧を取得
    const indexList = currentDb.getCollection(collection).getIndexKeys();

    // インデックスのヘッダーを表示(PlantUML)
    if (format === 'plantuml') {
      print(`    card ${collection.replaceAll("-", "_")}_index [`); // PlantUML対策
      print(`      Index`);
    }
    // 各インデックスに対して処理を行う
    indexList.forEach(index => {
      // インデックスを表示
      if (format === 'csv') {
        print(`,,"${JSON.stringify(index).replaceAll('"', '""')}"`);
      } else if (format === 'plantuml') {
        print(`      ....`)
        print(`      ${JSON.stringify(index)}`);
      } else {
        print(`    Index: ${JSON.stringify(index)}`);
      }
    });
    // コレクション終了(PlantUML)
    if (format === 'plantuml') {
      print(`    ]`);
      print(`  }`);
    }
  });
  // データベース終了(PlantUML)
  if (format === 'plantuml') {
    print('}');
  }
});

// フッター出力
if (format === 'plantuml') {
  print('@enduml');
}

こちらにも置いておいた。

使用方法

FORMAT環境変数にcsvorplantumlを入れるとそのフォーマットで表示される。そうでない場合テキストで。

# テキスト
$ mongosh mongodb://localhost:27017 -f getMongoCollections.js
# CSV
$ FORMAT=csv mongosh mongodb://localhost:27017 -f getMongoCollections.js > output.csv
# PlantUML
$ FORMAT=plantuml mongosh mongodb://localhost:27017 -f getMongoCollections.js > output.puml

サンプル出力結果

オープンソースのかんばんツールWekanはMongoDBを使っているので、それをDocker Composeで起動させその時のMongoDBのコレクション等をサンプルとして見てみる。

Compose.yaml
services:
  wekan:
    image: wekanteam/wekan
    ports:
      - "8080:8080"
    depends_on:
      - mongo
    environment:
      - ROOT_URL=http://localhost:8080
      - MONGO_URL=mongodb://mongo:27017/wekan
  mongo:
    image: mongo:latest
    volumes:
      - wekan-data:/data/db
    ports:
      - "27017:27017"

volumes:
  wekan-data:

テキスト

Database: wekan
  Collection: accountSettings
    Index: {"_id":1}
    Index: {"modifiedAt":-1}
  Collection: settings
    Index: {"_id":1}
    Index: {"modifiedAt":-1}
  Collection: invitation_codes
    Index: {"_id":1}
    Index: {"email":1}
    Index: {"modifiedAt":-1}
.
.
.

CSV

Markdownで例示するが、Execl等でも表にするとこんな感じ

Database Collection Index
wekan
accountSettings
{"_id":1}
{"modifiedAt":-1}
settings
{"_id":1}
{"modifiedAt":-1}
invitation_codes
{"_id":1}
{"email":1}
{"modifiedAt":-1}

生のCSVだと

Database,Collection,Index
wekan,,
,accountSettings,
,,"{""_id"":1}"
,,"{""modifiedAt"":-1}"
,settings,
,,"{""_id"":1}"
,,"{""modifiedAt"":-1}"
,invitation_codes,
,,"{""_id"":1}"
,,"{""email"":1}"
,,"{""modifiedAt"":-1}"
.
.
.

PlantUML

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?