MongoDBですべてのキーを列挙せずにサブフィールドをプロジェクションのトップレベルに昇格させる方法
はじめに
MongoDBの集計パイプライン(aggregation pipeline)では、ネストされたドキュメント内のサブフィールドを、すべてのキー名を手動で列挙することなくトップレベルに引き上げることが可能です。これを実現するには、$objectToArray 演算子と $arrayToObject 演算子を組み合わせて使用します。
本記事では、実際のコード例を交えながら、その手順をわかりやすく解説します。
サンプルデータの作成
まず、insertOne() メソッドを使ってドキュメントを挿入し、テスト用のコレクションを作成します。
> db.promoteSubfieldsDemo.insertOne({'s':10,'y':{'t':20,'u':30}})
{
"acknowledged" : true,
"insertedId" : ObjectId("5e038004190a577c668b55d5")
}
登録したドキュメントの確認
次に、find() メソッドを使用して、コレクション内のすべてのドキュメントを表示してみましょう。
> db.promoteSubfieldsDemo.find().pretty();
上記のクエリを実行すると、次のような出力が得られます。
{
"_id" : ObjectId("5e038004190a577c668b55d5"),
"s" : 10,
"y" : {
"t" : 20,
"u" : 30
}
}
ご覧のとおり、フィールド s はトップレベルにありますが、t と u はサブドキュメント y の中にネストされています。
サブフィールドをトップレベルに昇格させるクエリ
それでは、すべてのキーを一覧表示することなく、サブフィールドをトップレベルへ昇格させるクエリを見てみましょう。$replaceRoot ステージの中で、$arrayToObject・$concatArrays・$objectToArray を組み合わせて使用します。
> db.promoteSubfieldsDemo.aggregate([
... { "$replaceRoot": {
... "newRoot": {
... "$arrayToObject": {
... "$concatArrays": [
... [{ "k": "s", "v": "$s" }],
... { "$objectToArray": "$y" }
... ]
... }
... }
... }}
... ]);
このクエリを実行すると、次のようにサブフィールド t と u がトップレベルに展開された結果が出力されます。
{ "s" : 10, "t" : 20, "u" : 30 }
仕組みの解説
このアプローチのポイントは、以下の各演算子の役割にあります。
- $objectToArray: ドキュメントを「k(キー)」と「v(値)」のペアからなる配列に変換します。これにより、サブフィールドのキー名を事前に把握していなくても、動的に処理できるようになります。
- $concatArrays: 手動で定義した固定フィールド(例:
{ "k": "s", "v": "$s" })と、$objectToArray で変換したサブフィールドの配列を連結します。 - $arrayToObject: 連結後の配列を再び単一のドキュメント形式へと変換し直します。
- $replaceRoot: 変換結果のドキュメントを新しいルートとして置き換え、サブフィールドがトップレベルに昇格した状態を実現します。
この手法を活用すれば、キーの数が多いドキュメントや構造が不定なデータでも、柔軟にフィールドの階層をフラット化することができます。
-
MongoDBコレクションの全キー(フィールド名)を取得する方法まとめ
この記事は2019年1月18日にObjectRocket.com/blogで公開された内容をもとにしています。 MongoDB®のコレクションに含まれるすべてのキーを把握することは、スキーマの検証、フィールド名のタイプミスのデバッグ、設定すべきでないフィールドの発見など、さまざまな場面で役立ちます。本記事では、MongoDBコレクション内の全キー名を取得する複数の方法を、状況別にわかりやすく解説します。 まず検討したい:ODMやマネージドサービスの活用 ObjectRocketをはじめとする多くのMongoDB-as-a-Service事業者は、ユーザーインターフェース(UI)上で簡単にキーを
-
MongoDBコレクション内の全キー名を取得する方法|MapReduce・Aggregation・シェルなど状況別に解説
スキーマの検証、フィールド名のタイプミスのデバッグ、設定されるべきではないフィールドの発見などを行うには、まずMongoDBコレクション内にどのようなキーが存在するのかを把握しておく必要があります。多くのMongoDB-as-a-Service事業者は、UI上で手軽にこれを実現できる機能を提供しています(ObjectRocketもそのひとつです)。また、経験豊富なMongoDBユーザーの多くは、JavaScript向けのMongooseやPython向けのMongoengineといったオブジェクトドキュメントマッパー(ODM)を導入しています。ODMを使えば、アプリケーション向けの一貫性のある