データベース
 Computer >> コンピューター >  >> プログラミング >> データベース

MongoDBコレクションの全キー(フィールド名)を取得する方法まとめ

この記事は2019年1月18日にObjectRocket.com/blogで公開された内容をもとにしています。

MongoDB®のコレクションに含まれるすべてのキーを把握することは、スキーマの検証、フィールド名のタイプミスのデバッグ、設定すべきでないフィールドの発見など、さまざまな場面で役立ちます。本記事では、MongoDBコレクション内の全キー名を取得する複数の方法を、状況別にわかりやすく解説します。

まず検討したい:ODMやマネージドサービスの活用

ObjectRocketをはじめとする多くのMongoDB-as-a-Service事業者は、ユーザーインターフェース(UI)上で簡単にキーを確認できる機能を提供しています。また、経験豊富なMongoDBユーザーの多くは、JavaScript®向けのMongooseやPython®向けのMongoengineといったオブジェクトドキュメントマッパー(ODM)を導入し、アプリケーション用の一貫したスキーマを構築することでタイプミスを防いでいます。ODMは型のバリデーションも行ってくれるため、整数が入るはずのフィールドに誤って文字列を保存してしまうといったミスも未然に防げます。

ただし、こうしたサービスやODMを利用していない場合でも、いくつかの方法でキーにアクセスできます。以下に、目的に応じて使い分けられる代表的な手法を紹介します。

MongoDBのキーを調べる

例として、次のようなデータが登録されたコレクションを想定します。

db.activities.insert( { type : ['indoor', 'outdoor', 'mixed'] } );
db.activities.insert( { activity : 'cycling' } );
db.activities.insert( { activity : 'skiing', location: 'Alpes' } );
db.activities.insert( { equipment : ['paddles', 'sunglasses'] } );

この場合、取得したい一意なキーは「type」「activity」「equipment」「location」の4つです。

MapReduceを使う方法

MapReduceを利用すれば、次のコマンドでキーを取得できます。

mr = db.runCommand({ "mapreduce" : "activities", "map" : function() { for (var key in this) { emit(key, null); } }, "reduce" : function(key, stuff) { return null; }, "out": "activities" + "_keys" })

処理が完了したら、生成されたコレクションに対してdistinctコマンドを実行し、すべてのキーを取り出します。

db.activities_keys.distinct("_id")

サブドキュメント内の一意なキー一覧を取得したい場合は、map関数の該当行を次のように書き換えます。

for (var key in this.first_level.second_level.nth_level) { emit(key, null); }

アグリゲーション(Aggregation)を使う方法

アグリゲーションフレームワークを利用する方法もあります。この手法は、aggregateフレームワークをサポートするすべてのドライバーで動作します。オーバーヘッドを抑えたい場合は、$sample$limitを組み合わせると効果的です。

注意: プライマリの読み取り設定(read preference)で実行するとパフォーマンスに影響が出る可能性があります。セカンダリの読み取り設定での実行を検討してください。

バージョン3.4.4以降で利用可能な$objectToArrayを使うと、トップレベルのキーと値のペアを配列形式に変換できます。これに$unwind$group($addToSet)を組み合わせれば、コレクション全体から重複のないキー一覧を抽出できます。

次の例では、$$ROOTがトップレベルのドキュメントを参照しています。

db.activities.aggregate([ {"$project":{"arrayofkeyvalue":{"$objectToArray":"$$ROOT"}}}, {"$unwind":"$arrayofkeyvalue"}, {"$group":{"_id":null,"allkeys":{"$addToSet":"$arrayofkeyvalue.k"}}} ])

単一ドキュメントのキーだけを取得したい場合は、次のコマンドを使用します。

db.activities.aggregate([ {"$project":{"arrayofkeyvalue":{"$objectToArray":"$$ROOT"}}}, {"$project":{"keys":"$arrayofkeyvalue.k"}}} ])

Mongoシェルを使う方法

Mongoシェルクライアントからは、次のコマンドでキーを取得できます。

var allKeys = {}; db.YOURCOLLECTION.find().forEach(function(doc){Object.keys(doc).forEach(function(key){allKeys[key]=1})}); allKeys;

単一ドキュメントのフィールドを出力する方法

コレクション内の各ドキュメントがまったく異なるキーを持つこともあるため、特定の1件のドキュメントのフィールドだけを出力したいケースもあるでしょう。その場合は次のコマンドが便利です。

doc=db.thinks.findOne(); for (key in doc) print(key);

Pythonを使う方法

Python(pymongo)でもキーを取得できます。次の例では、コレクション内のすべてのトップレベルキーのセットを返します。

# pymongoと'db'という名前の接続を使用
reduce(
    lambda all_keys, rec_keys: all_keys | set(rec_keys),
    map(lambda d: d.keys(), db.things.find()),
    set()
)

JavaScript(Node.js)を使う方法

JavaScriptでも次のようにキーを取得できます。

db.collection('collectionName').mapReduce(
  function() { for (var key in this) { emit(key, null); } },
  function(key, stuff) { return null; },
  { "out": "allFieldNames" },
  function(err, results) {
    var fields = db.collection('allFieldNames').distinct('_id');
    fields
      .then(function(data) {
        var finalData = { "status": "success", "fields": data };
        res.send(finalData);
        deleteCollection(db, 'allFieldNames');
      })
      .catch(function(err) {
        res.send(err);
        deleteCollection(db, 'allFieldNames');
      });
  });

新しく作成されたallFieldNamesコレクションを読み取った後は、不要なデータが残らないよう削除しておきましょう。

db.collection("allFieldNames").remove({}, function (err,result) { db.close(); return; });

目的に合った方法を選ぼう

このように、MongoDBのキーを取得する方法は多数あります。大規模なコレクションにはアグリゲーション、手軽な確認にはMongoシェル、アプリケーションへの組み込みにはPythonやJavaScriptなど、用途や環境に応じて最適な手法を選択してください。

もしMongoDBの運用・管理に負担を感じており、データベース管理ではなくコード開発に集中したいのであれば、Rackspace DBA Servicesのようなマネージドサービスの活用も検討してみてください。

ご意見やご質問がある場合は、フィードバックタブからお気軽にお寄せください。いつでもお話ししましょう。

  1. C#のStringDictionaryでキーのコレクションを取得する方法

    C#のStringDictionaryでキーのコレクションを取得する方法 StringDictionaryからキーのコレクションを取得するには、Keysプロパティを使用します。このプロパティは、ディクショナリに格納されているすべてのキーをICollectionオブジェクトとして返します。 さらに、CopyToメソッドを組み合わせれば、取得したキーのコレクションを文字列配列(String[])にコピーでき、インデックスを指定して個々のキーにアクセスすることも可能です。 以下では、実際のサンプルコードと実行結果をもとに、具体的な手順を解説します。 例1:Keysプロパティでキーの一覧を取得する u

  2. MongoDBコレクション内の全キー名を取得する方法|MapReduce・Aggregation・シェルなど状況別に解説

    スキーマの検証、フィールド名のタイプミスのデバッグ、設定されるべきではないフィールドの発見などを行うには、まずMongoDBコレクション内にどのようなキーが存在するのかを把握しておく必要があります。多くのMongoDB-as-a-Service事業者は、UI上で手軽にこれを実現できる機能を提供しています(ObjectRocketもそのひとつです)。また、経験豊富なMongoDBユーザーの多くは、JavaScript向けのMongooseやPython向けのMongoengineといったオブジェクトドキュメントマッパー(ODM)を導入しています。ODMを使えば、アプリケーション向けの一貫性のある