Dodaj wyszukiwanie wektorowe Firestore do swoich aplikacji mobilnych dzięki rozszerzeniom w Firebase

1. Omówienie

Z tego ćwiczenia z programowania dowiesz się, jak dodać do aplikacji zaawansowane funkcje wyszukiwania za pomocą wyszukiwania podobieństwa wektorów w Firestore. Zaimplementujesz funkcję wyszukiwania semantycznego w aplikacji do robienia notatek napisanej w Swift i SwiftUI.

Konsola Cloud Firestore z kilkoma dokumentami, które są też widoczne po prawej stronie w aplikacji na iOS.

Czego się nauczysz

  • Jak zainstalować rozszerzenie wyszukiwania wektorów z Firestore, aby obliczyć wektory dystrybucyjne.
  • Jak wywołać funkcję Firebase Cloud Functions z aplikacji Swift.
  • Jak wstępnie filtrować dane na podstawie zalogowanego użytkownika.

Czego potrzebujesz

  • Xcode 15.3
  • Przykładowy kod w laboratorium kodu. Pobierzesz go w późniejszym kroku tego samouczka.

2. Tworzenie i konfigurowanie projektu Firebase

Aby korzystać z rozszerzenia Firebase Vector Search, musisz mieć projekt Firebase. W tej części tego ćwiczenia utworzysz nowy projekt Firebase i aktywujesz wymagane usługi, takie jak Cloud Firestore i Uwierzytelnianie Firebase.

Tworzenie projektu Firebase

  1. Zaloguj się w Firebase.
  2. W konsoli Firebase kliknij Dodaj projekt, a następnie nazwij swój projekt Firestore Vector Search Lab (Laboratorium wyszukiwania wektorowego)Tworzenie projektu, krok 1 z 3. Wybieranie nazwy projektu
  3. Przejrzyj opcje tworzenia projektu. Zaakceptuj warunki korzystania z Firebase, jeśli pojawi się taka prośba.
  4. Na ekranie Google Analytics odznacz pole Włącz Google Analytics w tym projekcie, ponieważ nie będziesz używać Analytics w tej aplikacji.
  5. Na koniec kliknij Utwórz projekt.

Więcej informacji o projektach Firebase znajdziesz w artykule Informacje o projektach Firebase.

Przejdź na wyższy abonament Firebase

Aby korzystać z rozszerzeń Firebase i podstawowych usług w chmurze, musisz mieć projekt Firebase w planie cen „płaca, ile używasz” (Blaze), co oznacza, że jest on połączony z kontem rozliczeniowym Cloud.

  • Konto Cloud Billing wymaga formy płatności, np. karty kredytowej.
  • Jeśli dopiero zaczynasz korzystać z Firebase i Google Cloud, sprawdź, czy kwalifikujesz się do otrzymania 300 USD środków i bezpłatnego okresu próbnego na koncie płatności Cloud.
  • Jeśli wykonujesz te ćwiczenia z programowania w ramach wydarzenia, zapytaj organizatora, czy są dostępne środki na Google Cloud.

Aby przenieść projekt na abonament Blaze:

  1. W konsoli Firebase wybierz uaktualnienie abonamentu.
  2. Wybierz abonament Blaze. Postępuj zgodnie z instrukcjami wyświetlanymi na ekranie, aby połączyć konto rozliczeniowe Cloud z projektem.
    Jeśli w ramach tego przejścia na wyższy poziom abonamentu musisz utworzyć konto rozliczeniowe Cloud, konieczne może być powrót do procesu przejścia w konsoli Firebase, aby go dokończyć.

Włączanie i konfigurowanie usług Firebase w konsoli

Tworzona przez Ciebie aplikacja korzysta z kilku usług Firebase dostępnych dla aplikacji Apple:

  • Uwierzytelnianie Firebase, aby umożliwić użytkownikom łatwe logowanie się w aplikacji.
  • Cloud Firestore do zapisywania ustrukturyzowanych danych w chmurze i otrzymywania natychmiastowych powiadomień o zmianach danych.
  • Reguły zabezpieczeń Firebase, aby zabezpieczyć bazę danych.

Niektóre z tych usług wymagają specjalnej konfiguracji lub ich włączenie musi nastąpić w konsoli Firebase.

Włączanie anonimowego uwierzytelniania w Uwierzytelnianiu Firebase

Aplikacja korzysta z uwierzytelniania anonimowego, aby umożliwić użytkownikom rozpoczęcie korzystania z aplikacji bez konieczności uprzedniego utworzenia konta. Dzięki temu proces wdrożenia jest prosty. Więcej informacji o anonimowym uwierzytelnianiu (oraz o tym, jak przejść na konto z nazwą) znajdziesz w artykule Sprawdzone metody dotyczące anonimowego uwierzytelniania.

  1. W panelu po lewej stronie w konsoli Firebase kliknij Kompilacja > Logowanie. Następnie kliknij Rozpocznij.Włączanie Uwierzytelniania Firebase
  2. Jesteś teraz w panelu uwierzytelniania, w którym możesz wyświetlać zarejestrowanych użytkowników, konfigurować dostawców logowania i zarządzać ustawieniami.
  3. Wybierz kartę Metoda logowania (lub kliknij tutaj, aby przejść bezpośrednio do tej karty).
  4. W opcjach dostawcy kliknij Anonimowe, ustaw przełącznik na Włącz, a potem kliknij Zapisz.

Konfigurowanie Cloud Firestore

Ta aplikacja w języku Swift zapisuje notatki za pomocą Cloud Firestore.

Aby skonfigurować Cloud Firestore w projekcie Firebase:

  1. W panelu po lewej stronie w konsoli Firebase rozwiń Kompilacja, a potem wybierz Baza danych Firestore.
  2. Kliknij Utwórz bazę danych.
  3. Pozostaw wartość (default) w polu Identyfikator bazy danych.
  4. Wybierz lokalizację bazy danych, a potem kliknij Dalej.
    W przypadku prawdziwej aplikacji wybierz lokalizację blisko użytkowników.
  5. Kliknij Rozpocznij w trybie testowym. Przeczytaj wyłączenie odpowiedzialności dotyczące reguł zabezpieczeń.
    W dalszej części tego ćwiczenia z programowania dodasz reguły zabezpieczeń, aby zabezpieczyć swoje dane. Nie udostępniaj ani nie udostępniaj publicznie aplikacji bez dodania reguł bezpieczeństwa dla bazy danych.
  6. Kliknij Utwórz.

Konfigurowanie Cloud Storage dla Firebase

Aplikacja internetowa używa Cloud Storage dla Firebase do przechowywania, przesyłania i udostępniania zdjęć.

Oto jak skonfigurować Cloud Storage dla Firebase w projekcie Firebase:

  1. W panelu po lewej stronie konsoli Firebase rozwiń Kompilacja, a potem kliknij Storage.
  2. Kliknij Rozpocznij.
  3. Wybierz lokalizację domyślnego zasobnika Storage.
    Zasobniki w regionach US-WEST1, US-CENTRAL1 i US-EAST1 mogą korzystać z poziomu Always Free w Google Cloud Storage. Zasobniki w innych lokalizacjach podlegają cennikom i zasadom korzystania z Google Cloud Storage.
  4. Kliknij Rozpocznij w trybie testowym. Przeczytaj wyłączenie odpowiedzialności dotyczące reguł bezpieczeństwa.
    W dalszej części tego Codelab dodasz reguły bezpieczeństwa, które ochronią Twoje dane. Nie udostępniaj ani nie udostępniaj publicznie aplikacji bez dodania reguł bezpieczeństwa dla zasobnika Storage.
  5. Kliknij Utwórz.

3. Połącz aplikację mobilną

W tej sekcji tego samouczka pobierzesz kod źródłowy prostej aplikacji do tworzenia notatek i połączysz ją z właśnie utworzonym projektem Firebase.

Pobieranie przykładowej aplikacji

  1. Otwórz stronę https://github.com/FirebaseExtended/codelab-firestore-vectorsearch-ios i skopiuj repozytorium na komputer lokalny.
  2. Otwórz projekt Notes.xcodeproj w Xcode.

Połącz aplikację z projektem Firebase

Aby aplikacja mogła uzyskać dostęp do usług Firebase, musisz ją skonfigurować w konsoli Firebase. Z tym samym projektem Firebase możesz połączyć wiele aplikacji klienckich. Jeśli na przykład tworzysz aplikację na Androida lub aplikację internetową, połącz je z tym samym projektem Firebase.

Więcej informacji o projektach Firebase znajdziesz w artykule Informacje o projektach Firebase.

  1. W konsoli Firebase otwórz stronę przeglądu projektu Firebase.Strona Przegląd w konsoli Firebase
  2. Kliknij ikonę iOS+, aby dodać aplikację na iOS.
  3. Na ekranie Dodaj Firebase do aplikacji Apple wpisz identyfikator pakietu z projektu Xcode (com.google.firebase.codelab.Notes).
  4. Możesz też wpisać pseudonim aplikacji (Uwagi dotyczące iOS).
  5. Aby przejść do następnego kroku, kliknij Zarejestruj aplikację.
  6. Pobierz plik GoogleServices-Info.plist.
  7. Przeciągnij plik GoogleServices-Info.plist do folderu Notes w projekcie Xcode. Najlepiej umieścić go pod plikiem Assets.xcassets.Przeciąganie pliku plist do Xcode
  8. W oknie Dodaj do kierowania kliknij W razie potrzeby skopiuj elementy i upewnij się, że wybrane jest ustawienie Notatki. Następnie kliknij Zakończ.W oknie wyboru opcji dodawania plików należy kliknąć „Kopiuj w razie potrzeby”.
  9. W konsoli Firebase możesz teraz przejść przez pozostałą część procesu konfiguracji: w pliku przykładowym pobranym na początku tej sekcji jest już zainstalowany pakiet SDK Firebase Apple i skonfigurowana jest inicjalizacja. Aby zakończyć proces, kliknij Przejdź do konsoli.

Uruchamianie aplikacji

Czas wypróbować aplikację.

  1. Wróć do Xcode i uruchom aplikację w Symulatorze iOS. W menu Miejsca docelowe uruchamiania wybierz najpierw jeden z symulatorów iOS.Wybieranie symulatora iOS w menu Miejsca docelowe uruchamiania
  2. Następnie kliknij przycisk Uruchom lub naciśnij ⌘ + R.
  3. Po uruchomieniu aplikacji w Symulatorze dodaj kilka notatek.
  4. W konsoli Firebase otwórz przeglądarkę danych Firestore, aby zobaczyć nowe dokumenty tworzone po dodaniu nowych notatek w aplikacji.Konsola Cloud Firestore z kilkoma dokumentami oraz symulatorem iOS, który wyświetla te same dokumenty

4. Instalowanie rozszerzenia Wyszukiwanie wektorowe w Firestore

W tej części tego samouczka zainstalujesz rozszerzenie Vector Search z Firestore i skonfigurujesz je zgodnie z wymaganiami aplikacji do tworzenia notatek, nad którą pracujesz.

Rozpocznij instalację rozszerzenia.

  1. W sekcji Firestore kliknij kartę Rozszerzenia.Wybieranie karty Rozszerzenia Firebase w konsoli Firestore
  2. Kliknij Przeglądaj Centrum rozszerzeń.Karta Rozszerzenia w Firebase w konsoli Firestore
  3. Wpisz „vector”.
  4. Kliknij „Wyszukiwanie wektorowe z rozszerzeniem Firestore”.Strona docelowa Firebase Extensions Hub Otworzy się strona z informacjami o rozszerzeniu, na której znajdziesz więcej informacji o tym, jak działa rozszerzenie, których usług Firebase wymaga i jak je skonfigurować.
  5. Kliknij Zainstaluj w konsoli Firebase.Przycisk instalacji rozszerzenia wyszukiwania wektorowego z Firestore
  6. Pojawi się lista wszystkich projektów.
  7. Wybierz projekt utworzony w pierwszym kroku tego samouczka.Ekran selektora projektów Firebase

Konfigurowanie rozszerzenia

  1. Sprawdź włączone interfejsy API i utworzone zasoby.Sprawdzanie włączonych interfejsów API
  2. Włącz wymagane usługi.Włączanie wymaganych usług
  3. Gdy wszystkie usługi są włączone, kliknij Dalej.Po włączeniu wszystkich usług kliknij Dalej
  4. Sprawdź uprawnienia dostępu przyznane temu rozszerzeniu.
  5. Skonfiguruj rozszerzenie:
    • Wybierz Vertex AI jako LLM.
    • Ścieżka kolekcji: notes
    • Domyślny limit zapytań: 3
    • Nazwa pola do wprowadzania danych: tekst
    • Nazwa pola wyjściowego: embedding
    • Nazwa pola stanu:* *status*
    • Umieszczanie istniejących dokumentów: tak
    • Aktualizowanie istniejących dokumentów: tak
    • Lokalizacja funkcji w Cloud Functions: us-central1
  6. Aby zakończyć instalację, kliknij Zainstaluj rozszerzenie.

Może to potrwać kilka minut. Podczas oczekiwania na zakończenie instalacji możesz przejść do następnej sekcji samouczka i przeczytać informacje wprowadzające na temat wektorów zanurzonych.

5. Tło

Podczas oczekiwania na zakończenie instalacji zapoznaj się z informacjami o działaniu rozszerzenia wyszukiwarki wektorowej z Firestore.

Czym są wektory, wektory dystrybucyjne i bazy danych wektorów?

  • Wektory to obiekty matematyczne, które reprezentują wielkość i kierunek wielkości. Mogą służyć do przedstawiania danych w sposób ułatwiający porównywanie i wyszukiwanie.
  • Reprezentacje właściwościowe to wektory reprezentujące znaczenie słowa lub wyrażenia. Są one tworzone przez trenowanie sieci neuronowej na dużym korpusie tekstów i uczenie się relacji między słowami.
  • Bazy danych wektorowych to bazy danych zoptymalizowane pod kątem przechowywania danych wektorowych i wyszukiwania w nich. Umożliwiają skuteczne wyszukiwanie najbliższych sąsiadów, czyli wyszukiwanie wektorów najbardziej podobnych do danego wektora zapytania.

Jak działa wyszukiwanie wektorowe?

Wyszukiwanie wektorowe polega na porównywaniu wektora zapytania ze wszystkimi wektorami w bazie danych. Wektory najbardziej podobne do wektora zapytania są zwracane jako wyniki wyszukiwania.

Podobieństwa między 2 wektorami można mierzyć za pomocą różnych wskaźników odległości. Najczęściej stosowanym wskaźnikiem odległości jest podobieństwo cosinusa, które mierzy kąt między dwoma wektorami.

6. Wypróbuj wyszukiwanie wektorowe z rozszerzeniem Firestore

Zanim użyjesz wyszukiwania wektorów z rozszerzeniem Firestore w aplikacji na iOS, którą pobrałeś(-aś) wcześniej w ramach tego ćwiczenia, możesz wypróbować to rozszerzenie w konsoli Firebase.

Przeczytaj dokumentację

Rozszerzenia Firebase zawierają dokumentację dotyczącą ich działania.

  1. Po zainstalowaniu rozszerzenia kliknij przycisk Rozpocznij. Strona przeglądu rozszerzenia Firebase w konsoli Firebase
  2. Na karcie „Jak działa to rozszerzenie” znajdziesz informacje o tym:
    • jak obliczyć embeddingi dokumentów, dodając je do kolekcji notes,
    • jak wysłać zapytanie do indeksu, wywołując funkcję ext-firestore-vector-search-queryCallable,
    • lub jak zapytać indeks, dodając do kolekcji _firestore-vector-search/index/queries dokument zapytania.
    • Wyjaśniono w nim też, jak skonfigurować niestandardową funkcję umieszczania – jest to przydatne, jeśli żaden z LLM obsługiwanych przez rozszerzenie nie spełnia Twoich wymagań i chcesz używać innego do ich obliczania. Dokumentacja rozszerzenia wyszukiwania wektorowego w Firestore
  3. Kliknij link Panel Cloud Firestore, aby przejść do instancji Firestore.
  4. Otwórz dokument _firestore-vector-search/index. Powinien on pokazywać, że rozszerzenie ukończyło obliczanie wektorów w przypadku wszystkich dokumentów z notatkami utworzonych w poprzednim kroku tego Codelab.Konfiguracja indeksu w konsoli Firestore
  5. Aby to sprawdzić, otwórz jeden z dokumentów z notatkami. Powinieneś zobaczyć dodatkowe pole o nazwie embedding typu vector<768>, a także pole status.Pole wektora dystrybucyjnego w konsoli Firestore

Tworzenie przykładowego dokumentu

Aby zobaczyć rozszerzenie w działaniu, możesz utworzyć nowy dokument w konsoli Firebase.

  1. Wciąż w przeglądarce danych Firestore przejdź do kolekcji notes i w środkowej kolumnie kliknij + Dodaj dokument.Dodawanie nowego dokumentu
  2. Kliknij Auto-ID, aby wygenerować nowy unikalny identyfikator dokumentu.
  3. Dodaj pole o nazwie text typu ciąg znaków i wklej tekst w polu wartość. Ważne, aby nie był to tekst Lorem Ipsum ani inny losowy tekst. Wybierz na przykład artykuł informacyjny.Dodawanie pola tekstowego
  4. Kliknij Zapisz.
    • Zwróć uwagę, że rozszerzenie dodaje pole stanu, aby wskazać, że przetwarza dane.
    • Po chwili powinno pojawić się nowe pole embedding o wartości vector<768>.
    Aktualizacja stanu wektorów zastępczych w nowym dokumencie

Wykonywanie zapytania

Rozszerzenie Wyszukiwanie wektorowe z Firestore ma przydatną funkcję, która pozwala wykonywać zapytania o indeks dokumentów bez konieczności łączenia aplikacji.

  1. W konsoli Firebase w sekcji Firestore otwórz dokument _firestore-vector-search/index.
  2. Kliknij + Utwórz kolekcjęDodawanie nowej podkolekcji.
  3. Utwórz nową podkolekcją o nazwie queries.
  4. Utwórz nowy dokument i ustaw pole query na tekst, który występuje w jednym z dokumentów. Najlepiej sprawdza się to w przypadku zapytań semantycznych, takich jak „Jak mogę zmapować dokumenty Firestore za pomocą Swifta” (o ile co najmniej jedna z dodanych notatek zawiera tekst na ten temat).Dodawanie pola zapytania
  5. W stanie może pojawić się błądWystąpił błąd
  6. Dzieje się tak, ponieważ brakuje indeksu. Aby skonfigurować brakujące ustawienie indeksu, otwórz konsolę Google Cloud dla projektu, klikając ten link i wybierając projekt z listy.Wybieranie odpowiedniego projektu
  7. W Eksploratorze logów Cloud powinien pojawić się komunikat o błędzie „FAILED_PRECondition: brak konfiguracji indeksu wektorów. Utwórz wymagany indeks za pomocą tego polecenia gcloud: ..."Komunikat o błędzie w eksploratorze logów
  8. Komunikat o błędzie zawiera też polecenie gcloud, które musisz uruchomić, aby skonfigurować brakujący indeks.
  9. Uruchom to polecenie w wierszu poleceń. Jeśli nie masz zainstalowanego interfejsu wiersza poleceń gcloud na komputerze, wykonaj te instrukcje, aby go zainstalować.
    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
    
    Tworzenie indeksu może potrwać kilka minut. Postęp możesz sprawdzić na karcie Indeksy w sekcji Firestore w konsoli Firebase.Stan nowego indeksu
  10. Po skonfigurowaniu indeksu możesz utworzyć nowy dokument zapytania.
  11. W polu wyników powinna teraz pojawić się lista pasujących identyfikatorów dokumentów.Wynik wykonania zapytania semantycznego
  12. Skopiuj jeden z tych identyfikatorów i wróć do kolekcji notes.
  13. Aby wyszukać skopiowany identyfikator dokumentu, użyj skrótu ⌘+F.Znajdowanie identyfikatora dokumentu na liście dokumentów

7. Implementacja wyszukiwania semantycznego

Nadszedł czas, aby połączyć aplikację mobilną z wyszukiwarką wektorową za pomocą rozszerzenia Firestore i wdrożyć funkcję wyszukiwania semantycznego, która pozwoli użytkownikom wyszukiwać notatki za pomocą zapytań w języku naturalnym.

Połącz funkcję wywołującą do wykonywania zapytań

Rozszerzenie Wyszukiwanie wektorowe w Firestore zawiera funkcję w Cloud Functions, którą możesz wywoływać z aplikacji mobilnej, aby wysyłać zapytania do indeksu utworzonego wcześniej w ramach tego ćwiczenia w Codelabs. Na tym etapie nawiążesz połączenie między aplikacją mobilną a tą wywoływalna funkcją. Pakiet SDK Firebase Swift zawiera interfejsy API, które ułatwiają wywoływanie funkcji zdalnych.

  1. Wróć do Xcode i sprawdź, czy korzystasz z projektu skopiowanego w poprzednim kroku tego ćwiczenia z programowania.
  2. Otwórz plik NotesRepository.swift.
  3. Odszukaj wiersz zawierający private lazy var vectorSearchQueryCallable: Callable = functions.httpsCallable("").

Aby wywołać funkcję wywołującą w Cloud Functions, musisz podać nazwę funkcji, którą chcesz wywołać.

  1. Otwórz konsolę Firebase swojego projektu i w sekcji Kompilacja kliknij menu Funkcje.
  2. Pojawi się lista funkcji zainstalowanych przez rozszerzenie.
  3. Wyszukaj plik o nazwie ext-firestore-vector-search-queryCallable i skopiuj jego nazwę.
  4. Wklej nazwę do kodu. Powinien on teraz wyglądać tak:
    private lazy var vectorSearchQueryCallable: Callable<String, String> = functions.httpsCallable("ext-firestore-vector-search-queryCallable")
    

Wywoływanie funkcji zapytania

  1. Znajdź metodę performQuery
  2. Wywołaj funkcję wywoływaną przez wywołanie
    let result = try await vectorSearchQueryCallable(searchTerm)
    

Ponieważ jest to wywołanie zdalne, może się nie udać.

  1. Dodaj podstawową obsługę błędów, aby przechwytywać błędy i rejestrować je w konsoli Xcode.
    private func performQuery(searchTerm: String) async -> [String] {
      do {
        let result = try await vectorSearchQueryCallable(searchTerm)
        return [result]
      }
      catch {
        print(error.localizedDescription)
        return []
      }
    }
    

Połącz interfejs

Aby umożliwić użytkownikom wyszukiwanie notatek, zaimplementuj pasek wyszukiwania na ekranie listy notatek. Gdy użytkownik wpisze wyszukiwane hasło, musisz wywołać metodę performQuery zaimplementowaną w poprzednim kroku. Dzięki dostępnym w SwiftUI modyfikatorom widoku searchable i task wystarczy dodać kilka wierszy kodu.

  1. Najpierw otwórz NotesListScreen.swift
  2. Aby dodać pole wyszukiwania do widoku listy, nad wierszem .navigationTitle("Notes") dodaj modyfikator widoku .searchable(text: $searchTerm, prompt: "Search")
  3. Następnie wywołaj funkcję wyszukiwania, dodając ten kod poniżej:
.task(id: searchTerm, debounce: .milliseconds(800)) {
  await notesRepository.semanticSearch(searchTerm: searchTerm)
}

Ten fragment kodu wywołuje metodę semanticSearch asynchronicznie. Jeśli ustawisz czas oczekiwania wynoszący 800 milisekund, modyfikator zadań ograniczy dane wejściowe użytkownika o 0,8 sekundy. Oznacza to, że funkcja semanticSearch zostanie wywołana dopiero wtedy, gdy użytkownik przerwie pisanie na ponad 0,8 sekund.

Twój kod powinien teraz wyglądać tak:

...
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")
...

Uruchom aplikację

  1. Aby uruchomić aplikację w Symulatorze iOS, naciśnij ⌘ + R (lub kliknij przycisk Uruchom).
  2. Powinny być widoczne te same notatki, które wcześniej dodałeś/dodałaś w aplikacji w ramach tego Codelab, a także notatki dodane w konsoli Firebase.
  3. Pole wyszukiwania powinno pojawić się u góry listy Uwagi.
  4. Wpisz termin, który występuje w jednym z dodanych dokumentów. Ponownie, najlepiej sprawdza się to w przypadku zapytań semantycznych, np. „Jak wywołać asynchroniczne interfejsy API Firebase z Swifta” (o ile co najmniej 1 dodany przez Ciebie tekst zawiera informacje na ten temat).
  5. Prawdopodobnie oczekujesz, że zobaczysz wyniki wyszukiwania, ale zamiast tego widok listy jest pusty, a konsola Xcode wyświetla komunikat o błędzie: „The function was called with an invalid argument” (Funkcja została wywołana z nieprawidłowym argumentem).

Aplikacja Notatki z pustą listą wyników

Oznacza to, że dane zostały przesłane w nieprawidłowym formacie.

Analiza komunikatu o błędzie

  1. Aby dowiedzieć się, co jest nie tak, otwórz konsolę Firebase.
  2. Otwórz sekcję Funkcje.
  3. Znajdź funkcję ext-firestore-vector-search-queryCallable. Otwórz rozszerzone menu, klikając 3 kropki w pionie.
  4. Wybierz Wyświetl logi, aby otworzyć eksplorator logów.
  5. Powinien pojawić się błąd
Unhandled error ZodError: [
  {
    "code": "invalid_type",
    "expected": "object",
    "received": "string",
    "path": [],
    "message": "Expected object, received string"
  }
]

Oznacza to, że dane zostały przesłane w nieprawidłowym formacie.

Używanie prawidłowych typów danych

Aby dowiedzieć się, w jakim formacie rozszerzenie oczekuje parametrów, zapoznaj się z dokumentacją rozszerzenia.

  1. W konsoli Firebase otwórz sekcję Rozszerzenia.
  2. Kliknij Zarządzaj >Zarządzanie wyszukiwaniem wektorowym za pomocą rozszerzenia Firestore.
  3. W sekcji Jak działa to rozszerzenie znajdziesz specyfikację parametrów wejściowych i wyjściowych.Dokumentacja parametru wejściowego i wartości wyniku
  4. Wróć do Xcode i przejdź do NotesRepository.swift.
  5. Dodaj na początku pliku ten kod:
    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 odpowiada strukturze parametru wejściowego, którego oczekuje rozszerzenie zgodnie z dokumentacją rozszerzenia. Zawiera też zagnieżdżoną właściwość prefilter, której będziesz potrzebować później. QueryResponse odpowiada strukturze odpowiedzi rozszerzenia.
  6. Znajdź specyfikację wywoływanej funkcji i zaktualizuj typy danych wejściowych i wyjściowych
    private lazy var vectorSearchQueryCallable: Callable<QueryRequest, QueryResponse> = functions.httpsCallable("ext-firestore-vector-search-queryCallable")
    
  7. Zaktualizuj wywołanie funkcji wywoływalnej w 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 []
      }
    }
    

Uruchom ponownie aplikację

  1. Uruchom ponownie aplikację
  2. Wpisz zapytanie zawierające terminy z jednego z Twoich notatek.
  3. Powinna być teraz widoczna przefiltrowana lista notatek

Zrzut ekranu aplikacji z oczekiwanym wynikiem

Filtrowanie wstępne danych użytkownika

Zanim zaczniesz tańczyć z radości, pamiętaj, że w obecnej wersji aplikacji występuje problem: zbiór wyników zawiera dane wszystkich użytkowników.

Możesz to sprawdzić, uruchamiając aplikację na innym symulatorze i dodając więcej dokumentów. Nowe dokumenty będą widoczne tylko w tym symulatorze. Jeśli uruchomisz aplikację ponownie w innym symulatorze, zobaczysz tylko dokumenty utworzone po raz pierwszy.

Jeśli wykonasz wyszukiwanie, zauważysz, że wywołanie funkcji vectorSearchQueryCallable zwraca identyfikatory dokumentów, które mogą należeć do innego użytkownika. Aby temu zapobiec, musimy użyć filtra wstępnego.

W pliku performQuery zaktualizuj kod w ten sposób:

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

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

Spowoduje to wstępne odfiltrowanie danych na podstawie identyfikatora zalogowanego użytkownika. Jak można się spodziewać, wymaga to zaktualizowania indeksu Firestore.

Uruchom podane niżej polecenie z poziomu wiersza poleceń, aby zdefiniować nowy indeks Firestore, który zawiera w polu embedding wektory dystrybucyjne zarówno userId, jak i wektory dystrybucyjne.

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

Po zakończeniu tworzenia indeksu uruchom aplikację ponownie, aby sprawdzić, czy działa zgodnie z oczekiwaniami.

Wstępnie przefiltrowany zestaw wyników

8. Gratulacje

Gratulacje! Ukończyłeś/ukończyłaś to ćwiczenie.

Z tego ćwiczenia na temat programowania dowiesz się, jak:

  • Skonfiguruj bazę danych Cloud Firestore z włączoną funkcją wyszukiwania semantycznego.
  • Utworzenie prostej aplikacji w SwiftUI do interakcji z bazą danych.
  • Zaimplementuj pasek wyszukiwania za pomocą modyfikatora widoku z możliwością wyszukiwania i modyfikatora zadania w SwiftUI.
  • Wywołaj funkcję Cloud Functions, aby przeprowadzić wyszukiwanie semantyczne w bazie danych, korzystając z interfejsu Callable w pakiecie SDK Firestore.

Dzięki wiedzy zdobytej w tym laboratorium programistycznym możesz teraz tworzyć wydajne aplikacje, które wykorzystują możliwości wyszukiwania semantycznego Cloud Firestore, aby zapewnić użytkownikom bardziej intuicyjne i wydajne wyszukiwanie.

Więcej informacji o nowym polu wektorów w Firestore i o tym, jak obliczać wektory dystrybucyjne wektorów, znajdziesz w dokumentacji.