>_tech-draft
Firebaseのアイコン
Firebase
動画公開日
タイトル

Firestore Enterprise: Mastering pipeline operations

再生時間

6分 5秒

Firestore Enterprise Editionで実現する高度なクエリ:Pipeline Operations徹底解説

ポイント

  • Firestore Enterprise EditionのPipeline Operationsは、Standard Editionでは困難だった高度なデータ変換や集計クエリを可能にします。
  • これは、配列の展開やフィールドの論理変換を複数ステージで組み合わせることで、複雑なデータ処理を実現する新しいクエリ機能です。
  • ただし、仮想フィールドはインデックス化されず、大規模データでのスキャンベースのクエリはパフォーマンスとコストに影響するため、利用時には注意が必要です。

本シリーズの前回の動画では、Firestoreのデータモデル、操作、用語、インデックス、そしてコアオペレーションのクエリ機能について詳しく解説し、これらの組み合わせがいかにスタンダードエディションでのFirestoreの一般的なクエリパフォーマンスを向上させるかをご説明しました。前回の動画の最後には、スタンダードエディションでは表現できないクエリの例を挙げました。具体的には、フィールドに直接保存されていない値による順序付けを伴うクエリです。このようなクエリは、Enterprise Editionでは実行可能です。なぜEnterprise Editionでこれが可能になるのかを理解するために、Firestore Enterprise Editionがどのようにクエリを処理するかについて掘り下げていきましょう。

Firestore Enterprise Editionとは?

従来のFirestoreクエリの限界

Firestoreのスタンダードエディションは、その設計上、特定の種類のクエリにおいて制約があります。特に、ドキュメントの特定のフィールドに直接紐づいていない値を基にした複雑なソートや集計は、効率的に行うことが困難でした。この限界を超えるために登場したのが、Firestore Enterprise Editionです。

Enterprise Editionの柔軟なクエリ機能

Enterprise Editionでは、Firestoreのクエリエンジンがより柔軟なクエリ解決戦略を実行できるようになります。これにより、私たちはより複雑なクエリを作成することが可能になります。具体的には、以下の機能が利用できます。

  • ドキュメントの直接スキャン: コレクション内のドキュメントを直接スキャンできます。
  • フィールド値の論理変換: ドキュメントのフィールド値に対して論理的な変換を実行できます。
  • インデックスのスキャン: インデックスを利用したスキャンが可能です。
  • 複数のスキャン結果の結合: 適切に定義されたインデックスのチャンクに結果が制約されないクエリを満たすために、単一のクエリで複数のスキャン結果を結合できます。

これらの高度なクエリ機能を、私たちは「Pipeline Operations(パイプライン操作)」と呼んでいます。これらは「Pipeline API」を通じてアクセスされます。

Pipeline Operationsとは

Enterprise Editionのクエリエンジンは、スタンダードエディションのクエリエンジンが可能な全てのことを実行できるため、全てのコアオペレーションクエリもパイプラインとして表現できます。既存のFirestoreユーザーのために、コアオペレーションクエリからパイプラインを作成するための便利なAPIも追加されています。

より柔軟なクエリエンジンは、例えば、フィールドをフィルタリングする前に変換したり、結果を単一の集計値にロールアップ(まとめる)してから返したりするようなことを可能にします。これをパイプライン操作と呼ぶのは、単一の操作内で複数のステージを組み合わせてデータをフェッチまたは変換し、そのデータを次のステージに供給できるためです。これは、お気に入りのプログラミング言語で配列に対して mapfilterreduce 関数を使用するのと非常によく似ています。

Pipeline Operationsの強力な機能と具体例

データ変換のステージング

パイプライン操作では、データを一連のステージを通して変換していきます。それぞれのステージは、入力されたデータをどのように変換するかを記述する1つ以上の「式」(Expression)で構成されます。式とは、フィールド宣言や全ての算術演算、文字列演算など、最終的に値に評価されるものです。

具体的な変換操作

Pipeline Operationsでは、以下のような多様なデータ変換を実行できます。

  • 文字列操作: 文字列をトリム、連結、大文字化、小文字化する。
  • 数値演算: 数値に対して算術演算を行う。
  • ドキュメントフィールドの追加と削除: ドキュメント全体にフィールドを追加したり削除したりする。
  • 配列の「Unnest」(展開): 配列を全く新しいドキュメントに展開する。

ユースケース:人気タグの集計

例えば、人々がレシピに材料やその他のメタデータとしてタグ付けできるレシピアプリを考えてみましょう。もし、全てのレシピで最も人気のあるタグをフェッチしたい場合、タグを独自のドキュメントに展開(unnest)し、展開されたタグ内で各タグがどれくらいの頻度で出現するかを単純にカウントすることができます。

Pipelineクエリの構築ステップ(タグ集計の例)

この複雑なクエリ宣言について、一行ずつ見ていきましょう。

1. 入力ステージの宣言

まず、パイプラインの入力ステージを宣言します。これは、パイプラインクエリが操作するコレクション、コレクショングループ、または個々のドキュメントのセットです。通常、これはパイプラインクエリから返される最大のドキュメントセットとなります。ただし、ドキュメントを展開(unnest)したり、別のパイプラインの結果を連結したりする場合は除きます。

2. 必要なフィールドの選択

入力から、ドキュメント内で必要なフィールドを選択します。人気タグ集計の例では tags フィールドのみを操作するため、ドキュメントの残りの部分は無視できます。select メソッドは入力として文字列を受け取り、読みやすい構文のために暗黙的にフィールド式に変換します。

3. 配列の「Unnest」(展開)

次に、文字列の配列を含む tags フィールドをunnestします。これにより、配列の要素ごとに1つの新しいドキュメントが生成され、配列要素の内容は tag name という新しいフィールドに格納されます。

4. 仮想フィールドと式

この tag name フィールドは「仮想的」なものであり、ドキュメントに書き戻されることはありません。これらの変換は全てメモリ内でのみ行われ、宣言されたパイプライン内でのみ有効です。しかし、パイプライン内では、他のドキュメントフィールドと同じくらい実体のあるものとして扱われます。これは仮想フィールドであるため、永続データベースに存在しないフィールドに対してインデックスを構築できないため、インデックスは存在しません。

5. Aggregate関数による集計

その後、Firestoreに対し、変更されたコレクションを反復処理し、以前に作成した tag name フィールドの各ユニークな値ごとにドキュメントをカウントするように指示します。異なるドキュメント内の同じタグは同じ tag name を持つため、この方法により、コレクション内で各タグが使用されている頻度を正確にカウントできます。これは aggregate 関数を使用することで実現します。aggregate 関数は、ドキュメント全体で結果を結合する特別なパイプラインステージであり、「Transformation Stage(変換ステージ)」と呼びます。変換ステージは、コレクション内のドキュメントごとではなく、ドキュメントのコレクション自体に対して操作を行うステージと考えることができます。

6. 結果のソート

最後に、最後の集計ステージで作成されたタグカウントによって、結果のコレクションをソートします。

Pipeline Operations利用時の考慮事項とパフォーマンス

これらの新しい表現力は、新たな責任を伴います。最も重要かつ最初の責任は、Firestoreがもはや、返されるドキュメントのサイズだけでスケーリングするクエリにあなたを制限しないことです。

スキャンベースのクエリとパフォーマンス

完全にインデックス化されていないコレクションの場合、Firestoreはコレクション内のドキュメントをスキャンしてクエリを実行します。これは、インデックス化されていないコレクションのクエリに対して線形時間(ドキュメントの数に比例)のパフォーマンスと課金を予想すべきであることを意味します。ドキュメントが多いほど、クエリは遅くなり、コストは高くなります。

仮想フィールドとインデックスの制約

パイプライン内の仮想フィールドは常にインデックス化されていないため、そのようなフィールドに対するソートやフィルタリングを伴うクエリは、インデックスの恩恵を受けることができません。例えば、前述のタグを全てカウントするクエリは、全てのタグをカウントするためにコレクション全体をスキャンすることが保証されます。したがって、大規模なレシピコレクションに対して複数のクライアントから同時に実行するような用途には適していません。しかし、cronジョブで定期的に実行するなどの用途であれば、問題ないでしょう。

Enterprise Editionのインデックス戦略のメリット

ただし、Firestore Enterprise Editionのインデックス戦略には利点もあります。インデックスはドキュメントデータを複製するため、インデックスがないことで保存するデータが少なくなり、ストレージコストが削減されます。また、非インデックスコレクションへの書き込み時にFirestoreがインデックスを更新する必要がないため、書き込みが高速になります。

まとめ

Firestore Enterprise EditionのPipeline Operationsは、従来のスタンダードエディションでは難しかった高度で柔軟なクエリを実現します。データの変換、集計、そして複雑な分析を、複数のステージを組み合わせて効率的に実行できる点が最大の魅力です。しかし、その強力な機能と引き換えに、クエリのパフォーマンスとコストに対する新たな責任も伴います。特に、非インデックスコレクションのスキャンや仮想フィールドの使用は、リソース消費に大きく影響するため、利用シナリオを慎重に検討することが重要です。

現時点ではまだ開発中の、リクエストの多いクエリタイプがいくつかあり、これらは本シリーズの新しい動画で紹介される予定です。もし特に見たい新しいクエリがあれば、ぜひコメント欄にご意見をお寄せください。

今回の記事で、パイプライン操作で可能なクエリとインデックスの仕組みを理解できたと思います。次回の動画では、この知識を組み合わせ、クエリのパフォーマンスに関する直感的な理解を深めていきましょう。

参考動画