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

Beyond the basics: How to build complex queries with Firestore’s new query engine

再生時間

7分 30秒

Firestoreの進化!複雑なクエリを可能にする新機能:全文検索とJOIN(サブクエリ)

ポイント

  • FirestoreのEnterprise Editionで提供される、全文検索とJOIN(サブクエリ)の強力な新機能について解説しています。
  • 全文検索は多様なキーワード検索と高度なマッチングを、サブクエリはドキュメントごとの集計や外部データの結合を実現します。
  • これらにより、従来の制限なく複雑な条件でのデータ探索やフィルタリング機能を柔軟に構築できる、Firestore開発者必読の進化です。

はじめに: Firebase Firestoreの強力な進化

皆さん、こんにちは。FirestoreチームのMorganです。本記事では、Firestoreを使って複雑な多段階クエリを記述する方法について詳しく解説します。アプリケーションを開発する際、データを保存し提供するためのデータベースは不可欠です。現代の急速に変化する世界では、新しい機能を迅速かつ表現豊かに構築するために、強力で柔軟なクエリ機能を備えたデータベースが求められます。

そこで登場するのが、Firebaseの主力NoSQLデータベースであるFirestoreです。Firestoreは、自動スケーリング、99.999%のSLAに裏打ちされた可用性、MongoDB互換性、クライアントSDKを介したオフラインキャッシュ、リアルタイムデータ同期を提供しています。さらに、今年のCloud Nextで発表された新機能として、全文検索地理空間クエリJOINデータ操作が加わりました。これらはFirestoreの歴史上、最も要望の多かった機能であり、今回は特に全文検索と**JOIN(サブクエリ)**について掘り下げていきます。

全文検索 (Full Text Search) の詳細

全文検索とは

名前が示す通り、全文検索はユーザーが馴染みのあるキーワードパターンを使用してドキュメントを検索する機能です。この機能は、ドキュメントデータをトークン化するテキストインデックスに依存した、異なるクエリ処理方法を使用します。

全文検索の仕組み

ユーザーが全文検索を実行すると、Firestoreは独自の検索モデルを適用してクエリを拡張し、ユーザーの意図にさらに完全に一致するようにします。そして、テキストインデックス内のトークンと照合します。結果はスコアリングされ、関連する各ドキュメントは検索スコアが追加されて返されます。スコアが高いほど、より良い一致を示します。これにより、検索クエリの結果が大きくなる可能性があるため、検索クエリを使用する際には、結果を制限したり、ページネーションしたりすることを忘れないでください。

Vector Searchとの違いとユースケース

Vector Searchとは異なり、全文検索はドキュメントデータやクエリのベクトル化を必要としません。また、ベクトル距離ではなく、テキストマッチングに基づいて結果をランク付けします。例えば、ECアプリを作成している場合、全文検索はユーザーが製品を見つけるための検索バーに適しています。一方、ユーザーが特定の製品ページを開いた後で類似製品を推奨するには、Vector Searchがより適しているでしょう。

全文検索でできること

全文検索では、以下のような操作が可能です。

  • 一般的な用語やフレーズでのクエリ: 馴染みのある形式で検索できます。
  • 同義語やバリエーションのネイティブマッチング: スペルの地域化など、自動的に対応します。
  • 検索条件の否定または結合: 1つの検索クエリ内で検索条件を組み合わせたり、否定したりできます。
  • 複数フィールドにわたる検索: 複数のフィールドを横断して検索クエリを実行できます。
  • 他の従来のフィルタリングクエリとの組み合わせ: 従来のフィルタリングと全文検索を一緒に使用することも可能です。

Joins(結合)とサブクエリ

次に、最も要望の多かったもう一つの機能であるJoinsについて見ていきましょう。Firestoreでは、Joinsはサブクエリとして実装されています。サブクエリは、別のクエリの結果を元のクエリのドキュメントに結合することを可能にする強力なクエリです。

サブクエリの活用例

  • コレクション内のドキュメントごとのクエリ実行: 例えば、コレクション内の各ドキュメントに対してクエリを実行し、その結果をマップフィールドとして追加することで、2つのドキュメントフィールドを効果的に結合できます。
  • サブクエリ内での集計: サブクエリ内で集計全体を実行することも可能です。

Firestore Enterprise Edition とパイプライン操作

これらの新しい機能は、Firestore Enterprise Editionによって実現されています。Enterprise Editionは、全く新しい高度なクエリエンジンを導入しており、「パイプライン操作 (pipeline operations)」と呼ばれる新しいカテゴリのクエリを提供します。これらのクエリは、複雑なステージをチェーンする(連結する)ことを可能にします。具体的には、以下のような操作が含まれます。

  • 配列フィールドのアンネスト
  • ドキュメントの分割
  • フィールドの切り捨てや追加
  • 複数のフィールドを単一のクエリで集約できる複雑な集計

サンプルアプリケーションでの活用事例: レシピアプリのフィルタリング

それでは、これらの新しい機能が実際のアプリケーションでどのように見えるかを見ていきましょう。ここでは、レシピの保存、共有、生成に使用されるレシピアプリを例に説明します。このアプリには、ユーザーが他のユーザーによって書かれたレシピを保存したりレビューしたりできるソーシャル機能が追加されています。

データモデル

データモデルは以下のようになっています。

  • recipes コレクション: 各ドキュメントには、レシピのテキスト、材料、著者情報、ユーザーが生成したタグが含まれます。
  • ソーシャル機能のために、saves コレクションと reviews コレクションがあります。
    • reviews コレクション: 評価値を含みます。
    • reviewssaves コレクションの両方に、ドキュメントを作成したユーザーのIDと、そのドキュメントが参照するレシピのIDが含まれます。

ユーザーが探しているレシピを見つけられるように、これらのソーシャル機能と組み合わせて何らかの発見可能性(Discoverability)が必要です。Firestoreの新しいクエリを使用してフィルタメニューを構築してみましょう。

フィルタメニューの構築

このメニューでは、単一のFirestoreパイプラインを使用し、ユーザーが選択する検索語やフィルターに応じてステージを条件付きで追加します。

1. 基本的なソートとフィルタリング

まず、基本的なソートとフィルタリングを作成します。これらは、過去にFirestoreを使用したことがある方には馴染みのあるクエリでしょう。単一のドキュメントフィールドに対する単純な等価性または順序付き不等価性マッチングです。例えば、正確な名前マッチングや配列のContains条件などが該当します。

2. パイプライン専用フィルタの追加(サブクエリの活用)

フィールドやタグのマッチングはかなり進みましたが、平均評価や「いいね」の総数によるソートなど、基本的な不等価性フィルタやソートがまだ不足しています。これらを追加するために、サブクエリを使用できます。

通常、不等価性フィルタの追加は非常に簡単です。Firestoreは、前述のフィルタのように単純な不等価性マッチングをサポートしているからです。しかし、今回マッチングしようとしている値(平均評価や「いいね」の総数)は、実際にはデータベースに存在しません。データモデルを思い出してください。データベースには個々の評価が保存されており、「いいね」の数はフィールドとして全く保存されていません。このような場合にサブクエリが必要となります。

平均値を保存したくない場合、ソートに必要な値はサブクエリで計算され、そのフィルタに渡されます。これは以下のように機能します。

パイプライン内で、さらに2つの追加パイプラインを作成します。1つは「いいね」を集計するため、もう1つは平均評価を集計するためです。次に、結果の値を親クエリのレシピドキュメントの2つの新しいフィールドに追加します。結果のドキュメントは、これらの新しく追加されたフィールドを含んだ形になります。

注意点: これらの新しく追加されたフィールドは、明示的にデータベースに書き戻さない限り永続化されません。平均評価や「いいね」の合計フィールドを単に保存する代わりにサブクエリを使用すると、書き込みはより単純で安価になりますが、読み取りコストは高くなります。より速い読み取りが必要で、書き込みが遅くなっても構わない場合は、事前に計算された集計値を保存し、トランザクションを介してそれを正確に更新することも常に可能です。

3. 検索の追加

最後に、クエリに検索機能を追加します。検索語をFirestoreに渡し、Firestoreが検索スコアを生成し、その検索スコアでソートするだけで完了です。構築した他のフィルタリングの前に検索クエリを追加することができ、これらはすべてうまく連携します。これにより、制限や「クエリがサポートされていません」といったエラーが発生することはありません。

まとめ

本記事では、Firestoreの新しい強力なクエリ機能、特に全文検索と**JOIN(サブクエリ)**について詳しく解説しました。Firestore Enterprise Editionによって導入された高度なクエリエンジンとパイプライン操作は、これまで不可能だった複雑なデータ操作と分析を可能にします。

平均評価や「いいね」の総数など、データベースに直接存在しない値を計算してソートやフィルタリングに利用できるサブクエリは、アプリケーション開発における柔軟性を大幅に向上させます。また、全文検索はユーザー体験を向上させるための重要な要素です。

これらの新機能を活用することで、よりリッチで高性能なアプリケーションを構築できるようになるでしょう。ぜひ、ドキュメントや提供されているサンプルコードを確認し、ご自身のプロジェクトでこれらの強力な機能を体験してみてください。

参考動画

Welcome back to the Firebase IO video series. I'm Morgan from the Fire Store team and I'm here today to talk you through how to write complex multi-stage queries using Fire Store.