Firebase Extensions を使用して Firestore ベクトル検索をモバイルアプリに追加する

1. 概要

この Codelab では、Firestore ベクトル類似性検索を使用して、強力な検索機能をアプリに追加する方法を学びます。Swift と SwiftUI で記述したメモ作成アプリ用にセマンティック検索機能を実装します。

いくつかのドキュメントを表示している Cloud Firestore コンソール。右側の iOS アプリにも表示されます。

学習内容

  • Firestore 拡張機能によるベクトル検索をインストールしてベクトル エンベディングを計算する方法。
  • Swift アプリケーションから Firebase Cloud Functions を呼び出す方法。
  • ログインしたユーザーに基づいてデータを事前フィルタする方法。

必要なもの

  • Xcode 15.3
  • Codelab のサンプルコード。これは、Codelab の後半のステップでダウンロードします。

2. Firebase プロジェクトを作成して設定する

Firebase ベクター検索拡張機能を使用するには、Firebase プロジェクトが必要です。Codelab のこのパートでは、新しい Firebase プロジェクトを作成し、Cloud Firestore や Firebase Authentication などの必要なサービスを有効にします。

Firebase プロジェクトを作成する

  1. Firebase にログインします。
  2. Firebase コンソールで [プロジェクトを追加] をクリックし、プロジェクトに Firestore ベクトル検索ラボという名前を付けます。プロジェクトを作成する、ステップ 1/3: プロジェクト名を選択する
  3. プロジェクト作成オプションをクリックします。プロンプトが表示されたら、Firebase の利用規約に同意します。
  4. Google アナリティクスの画面で、[このプロジェクトで Google アナリティクスを有効にする] チェックボックスをオフにします。このアプリではアナリティクスを使用しないためです。
  5. 最後に、[プロジェクトを作成] をクリックします。

Firebase プロジェクトの詳細については、Firebase プロジェクトについて理解するをご覧ください。

Firebase の料金プランをアップグレードする

Firebase Extensions とその基盤となるクラウド サービスを使用するには、Firebase プロジェクトが従量課金制(Blaze)のお支払いプランに登録されている必要があります。つまり、Cloud 請求先アカウントにリンクされている必要があります。

  • Cloud 請求先アカウントには、クレジット カードなどのお支払い方法が必要です。
  • Firebase と Google Cloud を初めて使用する場合は、$300 のクレジットと無料トライアル用 Cloud 請求先アカウントを利用できるかどうか確認してください。
  • この Codelab をイベントの一環として実施する場合は、利用可能な Cloud クレジットがあるかどうかを主催者に確認してください。

プロジェクトを Blaze プランにアップグレードする手順は次のとおりです。

  1. Firebase コンソールで、プランをアップグレードを選択します。
  2. Blaze プランを選択します。画面上の手順に沿って、Cloud 請求先アカウントをプロジェクトにリンクします。
    このアップグレードの一環として Cloud 請求先アカウントを作成する必要があった場合は、Firebase コンソールでアップグレード フローに移動してアップグレードを完了する必要があります。

コンソールで Firebase プロダクトを有効にして設定する

作成しているアプリでは、Apple アプリで使用できる次の Firebase プロダクトを使用します。

  • ユーザーがアプリに簡単にログインできるようにする Firebase Authentication
  • 構造化されたデータをクラウドに保存し、データが変更されたときに即座に通知を受け取る Cloud Firestore
  • データベースを保護するための Firebase セキュリティ ルール

この中には、特別な設定が必要になるプロダクトや、Firebase コンソールを使用して有効化する必要があるプロダクトがあります。

Firebase Authentication で匿名認証を有効にする

このアプリは匿名認証を使用しているため、ユーザーはアカウントを作成せずにアプリの使用を開始できます。これにより、スムーズなオンボーディング プロセスが実現します。匿名認証(および名前付きアカウントにアップグレードする方法)の詳細については、匿名認証のベスト プラクティスをご覧ください。

  1. Firebase コンソールの左側のパネルで、[Build] > [Authentication] をクリックします。[開始] をクリックします。Firebase Authentication の有効化
  2. 認証ダッシュボードでは、登録ユーザーの確認、ログイン プロバイダの設定、設定の管理を行えます。
  3. [ログイン方法] タブを選択します(または、ここをクリックしてタブに直接移動します)。
  4. プロバイダ オプションで [匿名] をクリックし、スイッチを [有効にする] に切り替えて、[保存] をクリックします。

Cloud Firestore を設定する

この Swift アプリケーションは、Cloud Firestore を使用してメモを保存します。

Firebase プロジェクトで Cloud Firestore を設定する方法は次のとおりです。

  1. Firebase コンソールの左側のパネルで [Build] を開き、[Firestore データベース] を選択します。
  2. [データベースを作成] をクリックします。
  3. [データベース ID] は (default) のままにします。
  4. データベースのロケーションを選択し、[次へ] をクリックします。
    実際のアプリの場合は、ユーザーに近いロケーションを選択します。
  5. [テストモードで開始] をクリックします。セキュリティ ルールに関する免責条項を確認します。
    この Codelab の後半で、セキュリティ ルールを追加してデータを保護します。データベースのセキュリティ ルールを追加せずに、アプリを配布または公開しないでください。
  6. [作成] をクリックします。

Cloud Storage for Firebase を設定する

このウェブアプリは Cloud Storage for Firebase を使用して画像ファイルを保存、アップロード、共有します。

Firebase プロジェクトで Cloud Storage for Firebase を設定する方法は次のとおりです。

  1. Firebase コンソールの左側のパネルで [ビルド] を開き、[Storage] を選択します。
  2. [開始] をクリックします。
  3. デフォルトの Storage バケットのロケーションを選択します。
    US-WEST1US-CENTRAL1US-EAST1 のバケットでは、Google Cloud Storage の「Always Free」階層を利用できます。他のすべてのロケーションのバケットは、Google Cloud Storage の料金と使用量に従います。
  4. [テストモードで開始] をクリックします。セキュリティ ルールに関する免責条項を確認します。
    この Codelab の後半で、セキュリティ ルールを追加してデータを保護します。Storage バケットのセキュリティ ルールを追加せずに、アプリを配布または公開しないでください。
  5. [作成] をクリックします。

3. モバイルアプリを接続する

この Codelab のセクションでは、シンプルなメモアプリのソースコードをダウンロードし、作成した Firebase プロジェクトに接続します。

サンプルアプリをダウンロードする

  1. https://github.com/FirebaseExtended/codelab-firestore-vectorsearch-ios に移動し、リポジトリをローカルマシンにクローンします。
  2. Xcode で Notes.xcodeproj プロジェクトを開きます。

アプリを Firebase プロジェクトに接続する

アプリが Firebase サービスにアクセスできるようにするには、Firebase コンソールでアプリを設定する必要があります。複数のクライアント アプリケーションを同じ Firebase プロジェクトに接続できます。たとえば、Android アプリやウェブアプリを作成する場合は、同じ Firebase プロジェクトに接続する必要があります。

Firebase プロジェクトの詳細については、Firebase プロジェクトについて理解するをご覧ください。

  1. Firebase コンソールで、Firebase プロジェクトの概要ページに移動します。Firebase コンソールの概要ページ
  2. iOS+ アイコンをクリックして iOS アプリを追加します。
  3. [Add Firebase to your Apple app] 画面で、Xcode プロジェクトのバンドル ID(com.google.firebase.codelab.Notes)を挿入します。
  4. 必要に応じて、アプリのニックネームを入力できます(iOS のメモ)。
  5. [アプリを登録] をクリックして次のステップに進みます。
  6. GoogleServices-Info.plist ファイルをダウンロードします。
  7. GoogleServices-Info.plist を Xcode プロジェクトの [Notes] フォルダにドラッグします。Assets.xcassets ファイルの下にドロップするのがおすすめです。plist ファイルを Xcode にドラッグする
  8. [Copy items if necessary] を選択し、[Add to targets] で [Notes] ターゲットが選択されていることを確認して、[Finish] をクリックします。ファイルの追加オプションを選択するダイアログで [必要に応じてコピー] を選択する
  9. Firebase コンソールで、残りの設定プロセスを進めることができます。このセクションの冒頭でダウンロードしたサンプルには、Firebase Apple SDK がすでにインストールされており、初期化も設定されています。[コンソールに進む] をクリックしてプロセスを完了します。

アプリを実行する

それでは、アプリを使ってみましょう。

  1. Xcode に戻り、iOS シミュレータでアプリを実行します。[実行先] プルダウンで、まずいずれかの iOS シミュレータを選択します。[実行先] プルダウンで iOS シミュレータを選択する
  2. [実行] ボタンをクリックするか、⌘ + R キーを押します。
  3. Simulator でアプリが正常に起動したら、いくつかのメモを追加します。
  4. Firebase コンソールで Firestore データブラウザに移動すると、アプリで新しいメモを追加するたびに作成される新しいドキュメントを確認できます。一部のドキュメントが表示されている Cloud Firestore コンソールと、同じドキュメントが表示されている iOS シミュレータ

4. Vector Search with Firestore 拡張機能をインストールする

この Codelab のパートでは、Firestore を使用したベクトル検索拡張機能をインストールし、作成中のメモアプリの要件に合わせて構成します。

拡張機能のインストールを開始する

  1. [Firestore] セクションで、[拡張機能] タブをクリックします。Firestore コンソールで [Firebase Extensions] タブを選択する
  2. [Extensions Hub を見る] をクリックします。Firestore コンソールの [Firebase Extensions] タブ
  3. 「vector」と入力します。
  4. [Firestore 拡張機能によるベクトル検索] をクリックします。Firebase Extensions Hub のランディング ページ拡張機能の詳細ページが表示され、この拡張機能の詳細、仕組み、必要な Firebase サービス、設定方法を確認できます。
  5. [Firebase コンソールでインストール] をクリックします。Firestore 拡張機能を使用したベクトル検索のインストール ボタン
  6. すべてのプロジェクトのリストが表示されます。
  7. この Codelab の最初の手順で作成したプロジェクトを選択します。Firebase プロジェクト選択画面

拡張機能の設定

  1. 有効な API と作成済みのリソースを確認します。有効な API の確認
  2. 必要なサービスを有効にします。必要なサービスを有効にする
  3. すべてのサービスが有効になったら、[次へ] をクリックします。すべてのサービスを有効にしてから [次へ] をクリックします
  4. この拡張機能に付与されているアクセス権を確認します。
  5. 拡張機能を構成します。
    • LLM として [Vertex AI] を選択します。
    • コレクションパス: notes
    • デフォルトのクエリの上限: 3
    • 入力フィールド名: text
    • 出力フィールド名: embedding
    • ステータス フィールド名:* *status*
    • 既存のドキュメントを埋め込む: はい
    • 既存のドキュメントを更新する: はい
    • Cloud Functions の関数のロケーション: us-central1
  6. [拡張機能をインストール] をクリックしてインストールを完了します。

この処理には数分かかることがあります。インストールが完了するまで待ちます。その間に、チュートリアルの次のセクションに進んで、ベクトル エンベディングに関する背景情報を確認してください。

5. 背景

インストールが完了するまでお待ちいただく間、Firestore を使用したベクトル検索拡張機能の仕組みについて説明します。

ベクトル、エンベディング、ベクトル データベースとは

  • ベクトルは、数量の大きさと方向を表す数学的オブジェクトです。比較や検索が容易な方法でデータを表現するために使用できます。
  • エンベディングは、単語やフレーズを表現するベクトルです。LLM は、大規模なテキストのコーパスでニューラル ネットワークをトレーニングし、単語間の関係を学習することで作成されます。
  • ベクトル データベースは、ベクトルデータの保存と検索に最適化されたデータベースです。これらのモデルを使用すると、特定のクエリベクトルに最も類似したベクトルを見つけるプロセスである、効率的な最近傍探索が可能になります。

ベクトル検索の仕組み

ベクトル検索は、クエリベクトルとデータベース内のすべてのベクトルを比較することで機能します。クエリベクトルに最も類似したベクトルが検索結果として返されます。

2 つのベクトルの類似性は、さまざまな距離指標を使用して測定できます。最も一般的な距離指標は、2 つのベクトル間の角度を測定するコサイン類似度です。

6. Firestore 拡張機能でベクトル検索を試す

この Codelab でダウンロードした iOS アプリで Firestore 拡張機能によるベクトル検索を使用する前に、Firebase コンソールで拡張機能を試すことができます。

ドキュメントを読む

Firebase Extensions には、その仕組みに関するドキュメントが含まれています。

  1. 拡張機能のインストールが完了したら、[使ってみる] ボタンをクリックします。Firebase コンソールの Firebase Extensions の概要ページ
  2. [この拡張機能の動作] タブで、以下の内容を確認します。
    • ドキュメントを notes コレクションに追加してドキュメントのエンベディングを計算する方法
    • ext-firestore-vector-search-queryCallable 呼び出し可能関数を呼び出してインデックスをクエリする方法
    • または、_firestore-vector-search/index/queries コレクションにクエリドキュメントを追加してインデックスをクエリする方法。
    • また、カスタム エンベディング関数の設定方法についても説明します。これは、拡張機能でサポートされている LLM がいずれも要件を満たしておらず、別の LLM を使用してエンベディングを計算したい場合に役立ちます。Firestore を使用したベクトル検索拡張機能のドキュメント
  3. [Cloud Firestore ダッシュボード] リンクをクリックして Firestore インスタンスに移動します。
  4. _firestore-vector-search/index ドキュメントに移動します。この Codelab の前の手順で作成したすべてのメモドキュメントのエンベディングの計算が拡張機能によって完了したことが示されます。Firestore コンソールのインデックス構成
  5. これを確認するには、メモドキュメントのいずれかを開きます。vector<768> 型の embedding という名前の追加フィールドと、status フィールドが表示されます。Firestore コンソールのベクトル エンベディング フィールド

サンプル ドキュメントを作成する

Firebase コンソールで新しいドキュメントを作成して、拡張機能の動作を確認できます。

  1. 引き続き Firestore データブラウザで、notes コレクションに移動し、中央の列にある [+ Add document] をクリックします。新しいドキュメントの追加
  2. [自動 ID] をクリックして、新しい一意のドキュメント ID を生成します。
  3. 文字列型の text という名前のフィールドを追加し、[] フィールドにテキストを貼り付けます。Lorem Ipsum などのランダムなテキストではなく、ニュース記事を選択します。テキスト フィールドの追加
  4. [保存] をクリックします。
    • 拡張機能にステータス フィールドが追加され、データの処理中であることが示されています。
    • しばらくすると、値が vector<768> の新しいフィールド embedding が表示されます。
    新しいドキュメントのベクトル エンベディングのステータスの更新

クエリを実行する

Firestore 拡張機能を使用したベクトル検索には、アプリを接続せずにドキュメント インデックスをクエリできる便利な機能があります。

  1. Firebase コンソールの Firestore セクションで、_firestore-vector-search/index ドキュメントに移動します。
  2. [+ コレクションを開始] をクリックします。新しいサブコレクションを追加する
  3. queries という名前の新しいサブコレクションを作成します。
  4. 新しいドキュメントを作成し、query フィールドをいずれかのドキュメントに存在するテキストに設定します。これは、「Firestore ドキュメントを Swift でマッピングするにはどうすればよいですか?」などの意味クエリに最適です(追加したメモの少なくとも 1 つに、このトピックについて説明するテキストが含まれている場合)。クエリ フィールドの追加
  5. ステータスにエラーが表示されることがあります。エラーが発生しました
  6. これは、インデックスがないためです。不足しているインデックス構成を設定するには、こちらのリンクからプロジェクトの Google Cloud コンソールに移動し、リストからプロジェクトを選択します。正しいプロジェクトの選択
  7. Cloud ログ エクスプローラに「FAILED_PRECONDITION: Missing vector index configuration. 次の gcloud コマンドを使用して、必要なインデックスを作成してください。"ログ エクスプローラのエラー メッセージ
  8. エラー メッセージには、不足しているインデックスを構成するために実行する必要がある gcloud コマンドも含まれています。
  9. コマンドラインから次のコマンドを実行します。マシンに gcloud CLI がインストールされていない場合は、こちらの手順に沿ってインストールします。
    gcloud alpha firestore indexes composite create --project=INSERT-YOUR=PROJECT-ID-HERE --collection-group=notes --query-scope=COLLECTION --field-config=vector-config='{"dimension":"768","flat": "{}"}',field-path=embedding
    
    インデックスの作成には数分かかります。進行状況は、Firebase コンソールの Firestore セクションの [インデックス] タブで確認できます。新しいインデックスのステータス
  10. インデックスが設定されたら、新しいクエリ ドキュメントを作成できます。
  11. 結果フィールドに、一致するドキュメント ID のリストが表示されます。セマンティック クエリの実行結果
  12. これらの ID のいずれかをコピーし、notes コレクションに戻ります。
  13. ⌘+F を使用して、コピーしたドキュメント ID を検索します。このドキュメントが、クエリに最もよく一致するドキュメントです。ドキュメントのリストでドキュメント ID を確認する

7. セマンティック検索を実装する

これで、モバイルアプリを Vector Search with Firestore 拡張機能に接続し、ユーザーが自然言語クエリを使用してメモを検索できるセマンティック検索機能を実装できます。

クエリを実行する呼び出し可能関数を接続する

Firestore のベクトル検索拡張機能には、モバイルアプリから呼び出して、この Codelab の前半で作成したインデックスをクエリできる Cloud Functions の関数が含まれています。このステップでは、モバイルアプリとこの呼び出し可能な関数の間に接続を確立します。Firebase の Swift SDK には、リモート関数の呼び出しをシームレスに行う API が含まれています。

  1. Xcode に戻り、この Codelab の前のステップでクローンを作成したプロジェクトにいることを確認します。
  2. NotesRepository.swift ファイルを開きます。
  3. private lazy var vectorSearchQueryCallable: Callable = functions.httpsCallable("") を含む行を見つけます。

呼び出し可能な Cloud Functions の関数を呼び出すには、呼び出す関数の名前を指定する必要があります。

  1. プロジェクトの Firebase コンソールに移動し、[Build] セクションで [Functions] メニュー アイテムを開きます。
  2. 拡張機能によってインストールされた関数のリストが表示されます。
  3. ext-firestore-vector-search-queryCallable という名前のものを検索し、その名前をコピーします。
  4. 名前をコードに貼り付けます。次のように変更します。
    private lazy var vectorSearchQueryCallable: Callable<String, String> = functions.httpsCallable("ext-firestore-vector-search-queryCallable")
    

クエリ関数を呼び出す

  1. メソッド performQuery を見つける
  2. 呼び出し可能関数を呼び出す
    let result = try await vectorSearchQueryCallable(searchTerm)
    

これはリモート呼び出しであるため、失敗する可能性があります。

  1. すべてのエラーをキャッチして Xcode のコンソールに記録するために、基本的なエラー処理を追加します。
    private func performQuery(searchTerm: String) async -> [String] {
      do {
        let result = try await vectorSearchQueryCallable(searchTerm)
        return [result]
      }
      catch {
        print(error.localizedDescription)
        return []
      }
    }
    

UI を接続する

ユーザーがメモを検索できるように、メモリスト画面に検索バーを実装します。ユーザーが検索キーワードを入力したときに、前のステップで実装した performQuery メソッドを呼び出す必要があります。SwiftUI が提供する searchable ビュー修飾子と task ビュー修飾子により、必要なコードは数行のみです。

  1. まず、NotesListScreen.swift を開きます。
  2. リストビューに検索ボックスを追加するには、.navigationTitle("Notes") 行のすぐ上に .searchable(text: $searchTerm, prompt: "Search") ビュー修飾子を追加します。
  3. 次に、検索関数を呼び出すため、そのすぐ下に次のコードを追加します。
.task(id: searchTerm, debounce: .milliseconds(800)) {
  await notesRepository.semanticSearch(searchTerm: searchTerm)
}

このコード スニペットでは、semanticSearch メソッドを非同期で呼び出します。タイムアウトを 800 ミリ秒に設定すると、ユーザーの入力を 0.8 秒デバウンスするようにタスク修飾子に指示します。つまり、semanticSearch はユーザーが入力を 0.8 秒以上一時停止した場合にのみ呼び出されます。

コードは次のようになります。

...
List(repository.notes) { note in
  NavigationLink(value: note) {
    NoteRowView(note: note)
  }
  .swipeActions {
    Button(role: .destructive, action: { deleteNote(note: note) }) {
      Label("Delete", systemImage: "trash")
    }
  }
}
.searchable(text: $searchTerm, prompt: "Search")
.task(id: searchTerm, debounce: .milliseconds(800)) {
  await notesRepository.semanticSearch(searchTerm: searchTerm)
}
.navigationTitle("Notes")
...

アプリを実行する

  1. ⌘+R キーを押す(または [実行] ボタンをクリック)して、iOS シミュレータでアプリを起動します
  2. この Codelab の前の方でアプリに追加したメモと、Firebase コンソールから追加したメモが表示されます。
  3. [メモ] リストの上部に検索欄が表示されます。
  4. 追加したドキュメントのいずれかに表示される用語を入力します。繰り返しになりますが、これは「Swift から非同期 Firebase API を呼び出すにはどうすればよいですか?」などのセマンティック クエリに最適です(追加したメモの少なくとも 1 つに、このトピックについて説明するテキストが含まれている場合)。
  5. 検索結果が表示されるはずが、リストビューは空で、Xcode コンソールに「The function was called with an invalid argument」というエラー メッセージが表示される

検索結果リストが空のメモアプリ

これは、データの形式が正しくないことを意味します。

エラー メッセージを分析する

  1. 問題を確認するには、Firebase コンソールに移動します。
  2. [関数] セクションに移動します。
  3. ext-firestore-vector-search-queryCallable 関数を見つけ、縦に並んだ 3 つの点をクリックしてオーバーフロー メニューを開きます。
  4. [ログを表示] を選択してログ エクスプローラに移動します。
  5. エラーが表示されます
Unhandled error ZodError: [
  {
    "code": "invalid_type",
    "expected": "object",
    "received": "string",
    "path": [],
    "message": "Expected object, received string"
  }
]

これは、データの形式が間違っていることを意味します。

適切なデータ型を使用する

拡張機能がパラメータに想定している形式を確認するには、拡張機能のドキュメントをご覧ください。

  1. Firebase コンソールの [Extensions] セクションに移動します。
  2. [管理 ->] Firestore 拡張機能によるベクトル検索の管理 をクリックします。
  3. 入力パラメータと出力パラメータの仕様については、この拡張機能の仕組みをご覧ください。入力パラメータと結果値のドキュメント
  4. Xcode に戻り、NotesRepository.swift に移動します。
  5. ファイルの先頭に次のコードを追加します。
    private struct QueryRequest: Codable {
      var query: String
      var limit: Int?
      var prefilters: [QueryFilter]?
    }
    
    private struct QueryFilter: Codable {
      var field: String
      var `operator`: String
      var value: String
    
    }
    
    private struct QueryResponse: Codable {
      var ids: [String]
    }
    
    QueryRequest は、拡張機能のドキュメントに従って、拡張機能が想定する入力パラメータの構造と一致します。また、後で必要になるネストされた prefilter 属性も含まれています。QueryResponse は拡張機能のレスポンスの構造と一致します。
  6. 呼び出し可能な関数の仕様を見つけて、入力と出力の型を更新する
    private lazy var vectorSearchQueryCallable: Callable<QueryRequest, QueryResponse> = functions.httpsCallable("ext-firestore-vector-search-queryCallable")
    
  7. performQuery で呼び出し可能関数の呼び出しを更新します。
    private func performQuery(searchTerm: String) async -> [String] {
      do {
        let queryRequest = QueryRequest(query: searchTerm,
                                        limit: 2)
        let result = try await vectorSearchQueryCallable(queryRequest)
        print(result.ids)
        return result.ids
      }
      catch {
        print(error.localizedDescription)
        return []
      }
    }
    

アプリを再度実行する

  1. アプリを再実行する
  2. メモに含まれている語句を含む検索クエリを入力します
  3. フィルタされたメモのリストが表示されます。

期待される結果が表示されたアプリのスクリーンショット

ユーザーデータを事前フィルタする

喜びのあまり踊り出す前に、現在のバージョンのアプリには問題があることを知っておいてください。結果セットにはすべてのユーザーのデータが含まれています。

別のシミュレータでアプリを実行し、ドキュメントを追加することでこれを確認できます。新しいドキュメントは、そのシミュレータにのみ表示されます。別のシミュレータでアプリを再度実行すると、最初に作成したドキュメントのみが表示されます。

検索を実行すると、vectorSearchQueryCallable の呼び出しによって、他のユーザーに属している可能性のあるドキュメント ID が返されます。これを防ぐには、プリフィルタを使用する必要があります。

performQuery で、コードを次のように更新します。

  let prefilters: [QueryFilter] = if let uid = user?.uid {
    [QueryFilter(field: "userId", operator: "==", value: uid)]
  }
  else {
    []
  }

  let queryRequest = QueryRequest(query: searchTerm,
                                  limit: 2,
                                  prefilters: prefilters)

これにより、ログイン中のユーザーの ID に基づいてデータが事前フィルタされます。当然ながら、これを行うには Firestore インデックスを更新する必要があります。

コマンドラインから次のコマンドを実行して、embedding フィールドに userId とベクトル エンベディングの両方を含む新しい Firestore インデックスを定義します。

gcloud alpha firestore indexes composite create --project=INSERT-YOUR-PROJECT-ID-HERE --collection-group=notes --query-scope=COLLECTION --field-config=order=ASCENDING,field-path=userId --field-config=vector-config='{"dimension":"768","flat": "{}"}',field-path=embedding

インデックスのビルドが完了したら、アプリをもう一度実行して、想定どおりに動作することを確認します。

事前フィルタされた結果セット

8. 完了

これでこの Codelab は終了です。

この Codelab では、以下の方法を学びました。

  • セマンティック検索を有効にして Cloud Firestore データベースを設定する。
  • データベースを操作するシンプルな SwiftUI アプリを作成します。
  • SwiftUI の検索可能なビュー修飾子とタスク修飾子を使用して検索バーを実装します。
  • Cloud Functions を呼び出して、Firestore SDK の Callable インターフェースを使用してデータベースでセマンティック検索を実行します。

この Codelab で学んだ知識を活用して、Cloud Firestore のセマンティック検索機能を活用し、より直感的で効率的な検索エクスペリエンスをユーザーに提供する強力なアプリケーションを構築できます。

Firestore の新しいベクトル フィールドとベクトル エンベディングの計算方法について詳しくは、ドキュメントをご覧ください。