Добавьте векторный поиск Firestore в свои мобильные приложения с помощью расширений Firebase

1. Обзор

В этом практическом занятии вы узнаете, как добавить мощные функции поиска в ваше приложение, используя векторный поиск сходства Firestore . Вы реализуете функцию семантического поиска для приложения для ведения заметок, написанного на Swift и SwiftUI.

В консоли Cloud Firestore отображаются некоторые документы, которые также видны в приложении iOS в правой части экрана.

Что вы узнаете

  • Как установить расширение Vector Search with Firestore для вычисления векторных представлений.
  • Как вызывать Firebase Cloud Functions из приложения Swift.
  • Как выполнить предварительную фильтрацию данных на основе авторизованного пользователя.

Что вам понадобится

  • Xcode 15.3
  • Пример кода для Codelab. Вы сможете скачать его на следующем этапе Codelab.

2. Создайте и настройте проект Firebase.

Для использования расширения Firebase Vector Search вам потребуется проект Firebase. В этой части практического занятия вы создадите новый проект Firebase и активируете необходимые сервисы, такие как Cloud Firestore и Firebase Authentication.

Создайте проект Firebase.

  1. Войдите в консоль Firebase, используя свою учетную запись Google.
  2. Нажмите кнопку, чтобы создать новый проект, а затем введите название проекта (например, Firestore Vector Search Codelab ).
  3. Нажмите «Продолжить» .
  4. Если появится запрос, ознакомьтесь с условиями использования Firebase и примите их, после чего нажмите «Продолжить» .
  5. (Необязательно) Включите помощь ИИ в консоли Firebase (в Firebase она называется "Gemini").
  6. Для этого практического занятия вам не понадобится Google Analytics, поэтому отключите эту опцию.
  7. Нажмите «Создать проект» , дождитесь завершения подготовки проекта, а затем нажмите «Продолжить» .

Чтобы узнать больше о проектах Firebase, см. раздел «Понимание проектов Firebase» .

Обновите свой тарифный план Firebase.

Для использования расширений Firebase и облачных сервисов, на которых они основаны, ваш проект Firebase должен использовать тарифный план с оплатой по мере использования (Blaze) , то есть быть привязан к учетной записи Cloud Billing .

Чтобы перейти на тарифный план Blaze для вашего проекта, выполните следующие шаги:

  1. В консоли Firebase выберите вариант обновления вашего тарифного плана .
  2. Выберите тарифный план Blaze. Следуйте инструкциям на экране, чтобы связать учетную запись Cloud Billing с вашим проектом.
    Если в рамках этого обновления вам потребовалось создать учетную запись Cloud Billing, возможно, вам нужно будет вернуться к процессу обновления в консоли Firebase, чтобы завершить обновление.

Включение и настройка продуктов Firebase в консоли.

В разрабатываемом вами приложении используется несколько продуктов Firebase, доступных для приложений Apple:

  • Аутентификация Firebase позволит вашим пользователям легко входить в систему вашего приложения.
  • Cloud Firestore позволяет сохранять структурированные данные в облаке и получать мгновенные уведомления об изменениях данных.
  • Правила безопасности Firebase для защиты вашей базы данных.

Для некоторых из этих продуктов требуется специальная настройка или их включение через консоль Firebase.

Включите анонимную аутентификацию для Firebase Authentication

Это приложение использует анонимную аутентификацию , позволяя пользователям начать работу с приложением без предварительного создания учетной записи. Это обеспечивает простой процесс регистрации. Чтобы узнать больше об анонимной аутентификации (и о том, как перейти на именованную учетную запись), см. раздел «Рекомендации по использованию анонимной аутентификации» .

  1. В левой панели консоли Firebase нажмите Build > Authentication . Затем нажмите Get started . Включение аутентификации Firebase
  2. Теперь вы находитесь на панели управления аутентификацией, где можете просмотреть зарегистрированных пользователей, настроить поставщиков авторизации и управлять параметрами.
  3. Выберите вкладку «Способ входа» (или нажмите здесь, чтобы перейти непосредственно к этой вкладке).
  4. В параметрах поставщика услуг выберите «Анонимный» , переведите переключатель в положение «Включить» , а затем нажмите «Сохранить» .

Настройка Cloud Firestore

Это приложение на Swift использует Cloud Firestore для сохранения заметок.

Вот как настроить Cloud Firestore в вашем проекте Firebase:

  1. В левой панели консоли Firebase разверните раздел «Сборка» , а затем выберите базу данных Firestore .
  2. Нажмите «Создать базу данных» .
  3. Оставьте значение параметра " Идентификатор базы данных" равным (default) .
  4. Выберите местоположение для вашей базы данных, затем нажмите «Далее» .
    Для создания настоящего приложения вам следует выбрать местоположение, расположенное недалеко от ваших пользователей.
  5. Нажмите «Пуск» в тестовом режиме . Ознакомьтесь с отказом от ответственности в отношении правил безопасности.
    В дальнейшем в этом практическом занятии вы добавите правила безопасности для защиты ваших данных. Не распространяйте и не предоставляйте публичный доступ к приложению, не добавив правила безопасности для вашей базы данных.
  6. Нажмите «Создать» .

Настройка облачного хранилища для Firebase

Веб-приложение использует Cloud Storage for Firebase для хранения, загрузки и обмена фотографиями.

Вот как настроить Cloud Storage для Firebase в вашем проекте Firebase:

  1. В левой панели консоли Firebase разверните раздел «Сборка» , а затем выберите «Хранилище» .
  2. Нажмите « Начать» .
  3. Выберите местоположение для вашего хранилища по умолчанию.
    Для регионов US-WEST1 , US-CENTRAL1 и US-EAST1 доступен тариф "Всегда бесплатно" от Google Cloud Storage. Для регионов во всех остальных регионах действуют тарифные планы и правила использования Google Cloud Storage .
  4. Нажмите «Пуск» в тестовом режиме . Ознакомьтесь с отказом от ответственности в отношении правил безопасности.
    В дальнейшем в этом практическом занятии вы добавите правила безопасности для защиты ваших данных. Не распространяйте и не предоставляйте публичный доступ к приложению без добавления правил безопасности для вашего хранилища.
  5. Нажмите «Создать» .

3. Подключите мобильное приложение.

В этом разделе практического занятия вы загрузите исходный код простого приложения для ведения заметок и подключите его к только что созданному проекту Firebase.

Скачайте демонстрационное приложение

  1. Перейдите по ссылке https://github.com/FirebaseExtended/codelab-firestore-vectorsearch-ios и клонируйте репозиторий на свой локальный компьютер.
  2. Откройте проект Notes.xcodeproj в Xcode.

Подключите приложение к вашему проекту Firebase.

Для того чтобы ваше приложение могло получить доступ к сервисам Firebase, вам необходимо настроить его в консоли Firebase. Вы можете подключить несколько клиентских приложений к одному и тому же проекту Firebase; например, если вы создаете приложение для Android или веб-приложение, вам следует подключить их к одному и тому же проекту Firebase.

Чтобы узнать больше о проектах Firebase, см. раздел «Понимание проектов Firebase» .

  1. В консоли Firebase перейдите на страницу обзора вашего проекта Firebase. Обзорная страница консоли Firebase
  2. Нажмите на значок iOS+, чтобы добавить свое iOS-приложение.
  3. На экране «Добавить Firebase в ваше приложение Apple» вставьте идентификатор пакета из проекта Xcode ( com.google.firebase.codelab.Notes ).
  4. При желании вы можете ввести псевдоним приложения (например, Notes для iOS ).
  5. Нажмите «Зарегистрировать приложение», чтобы перейти к следующему шагу.
  6. Загрузите файл GoogleServices-Info.plist .
  7. Перетащите файл GoogleServices-Info.plist в папку Notes вашего проекта Xcode. Удобнее всего сделать это, поместив его под файл Assets.xcassets . Перетаскивание файла plist в Xcode
  8. Выберите пункт «Копировать элементы при необходимости» , убедитесь, что в поле «Добавить в целевые объекты» выбран объект «Примечания» , и нажмите «Готово» . Выберите пункт «Копировать при необходимости» в диалоговом окне выбора параметров добавления файлов.
  9. В консоли Firebase теперь можно пройти оставшуюся часть процесса настройки: в загруженном вами в начале этого раздела примере уже установлен Firebase Apple SDK и настроена инициализация. Завершить процесс можно, нажав кнопку «Продолжить в консоли» .

Запустите приложение

Пришло время опробовать приложение в действии!

  1. Вернитесь в Xcode и запустите приложение на симуляторе iOS. В раскрывающемся списке «Места запуска» сначала выберите один из симуляторов iOS. Выбор симулятора iOS в раскрывающемся списке «Места запуска»
  2. Затем нажмите кнопку «Выполнить» или нажмите ⌘ + R.
  3. После успешного запуска приложения в симуляторе добавьте пару заметок.
  4. В консоли Firebase перейдите в браузер данных Firestore, чтобы увидеть, как создаются новые документы по мере добавления новых заметок в приложение. В консоли Cloud Firestore отображаются некоторые документы, а в симуляторе iOS — те же самые документы.

4. Установите расширение Vector Search with Firestore.

В этой части практического занятия вы установите расширение Vector Search with Firestore и настроите его в соответствии с требованиями приложения для ведения заметок, над которым вы работаете.

Начните установку расширения

  1. Оставаясь в разделе Firestore, перейдите на вкладку «Расширения» . Выберите вкладку «Расширения Firebase» в консоли Firestore.
  2. Нажмите на «Изучить центр расширений». Вкладка «Расширения Firebase» в консоли Firestore.
  3. Введите "вектор".
  4. Нажмите на кнопку "Векторный поиск с помощью расширения Firestore". Главная страница Firebase Extensions Hub Это переведет вас на страницу с подробной информацией о расширении, где вы сможете узнать больше о нем, о том, как оно работает, какие сервисы Firebase ему требуются и как его настроить.
  5. Нажмите «Установить» в консоли Firebase . Кнопка установки расширения Vector Search with Firestore
  6. Вам будет представлен список всех ваших проектов.
  7. Выберите проект, который вы создали на первом этапе этого практического занятия. Экран выбора проекта Firebase

Настройте расширение

  1. Проверьте, какие API включены и какие ресурсы созданы. Проверка включенных API.
  2. Включите необходимые службы. Включение необходимых сервисов
  3. После включения всех служб нажмите кнопку «Далее» . После включения всех служб нажмите «Далее».
  4. Проверьте предоставленный доступ к этому расширению.
  5. Настройте расширение:
    • Выберите Vertex AI в качестве магистра права.
    • Путь к коллекции : заметки
    • Ограничение на количество запросов по умолчанию : 3
    • Название поля ввода : текст
    • Название выходного поля: embedding
    • Название поля «Статус»: * *status*
    • Встроить существующие документы : Да
    • Обновить существующие документы : Да
    • Расположение облачных функций : us-central1
  6. Нажмите «Установить расширение» , чтобы завершить установку.

Это может занять пару минут. Пока вы ждете завершения установки, можете перейти к следующему разделу руководства и ознакомиться с дополнительной информацией о векторных представлениях.

5. Предыстория

Пока вы ждете завершения установки, вот некоторая справочная информация о том, как работает расширение Vector Search with Firestore.

Что такое векторы, эмбеддинги и векторные базы данных?

  • Векторы — это математические объекты, представляющие величину и направление значения. Они могут использоваться для представления данных таким образом, чтобы упростить сравнение и поиск.
  • Встраивания — это векторы, представляющие значение слова или фразы. Они создаются путем обучения нейронной сети на большом корпусе текста и изучения взаимосвязей между словами.
  • Векторные базы данных — это базы данных, оптимизированные для хранения и поиска векторных данных. Они позволяют эффективно осуществлять поиск ближайшего соседа, то есть процесс нахождения наиболее похожих векторов на заданный вектор запроса.

Как работает векторный поиск?

Векторный поиск работает путем сравнения вектора запроса со всеми векторами в базе данных. В качестве результатов поиска возвращаются векторы, наиболее похожие на вектор запроса.

Сходство между двумя векторами можно измерить с помощью различных метрик расстояния. Наиболее распространенной метрикой расстояния является косинусное сходство, которое измеряет угол между двумя векторами.

6. Попробуйте расширение Vector Search with Firestore.

Прежде чем использовать расширение Vector Search with Firestore в iOS-приложении, которое вы скачали ранее в этом практическом занятии, вы можете протестировать расширение в консоли Firebase.

Ознакомьтесь с документацией.

Расширения Firebase содержат документацию, описывающую принцип их работы.

  1. После завершения установки расширения нажмите кнопку «Начать» . Страница обзора расширений Firebase в консоли Firebase
  2. Ознакомьтесь с вкладкой «Как работает это расширение» — там все объяснено:
    • Как вычислить векторные представления документов, добавив их в коллекцию notes ?
    • Как выполнить запрос к индексу, вызвав вызываемую функцию ext-firestore-vector-search-queryCallable ?
    • или как выполнить запрос к индексу, добавив документ запроса в коллекцию _firestore-vector-search/index/queries .
    • В нем также объясняется, как настроить пользовательскую функцию встраивания — это полезно, если ни одна из поддерживаемых расширением функций LLM не соответствует вашим требованиям, и вы хотели бы использовать другую функцию LLM для вычисления встраиваний. Документация по расширению Vector Search with Firestore
  3. Чтобы перейти к своему экземпляру Firestore, нажмите на ссылку панели управления Cloud Firestore.
  4. Перейдите к документу _firestore-vector-search/index . Там должно отобразиться сообщение о том, что расширение завершило вычисление эмбеддингов для всех документов заметок, созданных вами на предыдущем шаге этого практического занятия. Настройка индекса в консоли Firestore.
  5. Чтобы это проверить, откройте один из документов с заметками, и вы увидите дополнительное поле с именем embedding типа vector<768> , а также поле status . Поле для встраивания векторов в консоли Firestore.

Создать образец документа

Чтобы увидеть расширение в действии, вы можете создать новый документ в консоли Firebase.

  1. Оставаясь в браузере данных Firestore, перейдите к коллекции notes и нажмите кнопку «+ Добавить документ» в среднем столбце. Добавление нового документа
  2. Нажмите кнопку «Автоматическая идентификация» , чтобы сгенерировать новый уникальный идентификатор документа.
  3. Добавьте поле с именем text типа string и вставьте в него какой-нибудь текст. Важно, чтобы это не был текст типа lorem ipsum или какой-либо другой случайный текст. Например, выберите новостную статью. Добавление текстового поля
  4. Нажмите « Сохранить ».
    • Обратите внимание, как расширение добавляет поле статуса, указывающее на то, что оно обрабатывает данные.
    • Через короткое время вы должны увидеть новое поле, embedding вектор, со значением vector<768> .
    Обновление статуса векторных представлений для нового документа.

Выполните запрос

Расширение Vector Search with Firestore обладает удобной функцией, позволяющей выполнять запросы к индексу документов без необходимости подключения приложения.

  1. В разделе Firestore консоли Firebase перейдите к документу _firestore-vector-search/index
  2. Нажмите + Начать сбор Добавление новой подколлекции
  3. Создайте новую подколлекцию с именем queries
  4. Создайте новый документ и установите поле query на текст, который встречается в одном из ваших документов. Это лучше всего подходит для семантических запросов, например, "Как сопоставить документы Firestore с Swift" (при условии, что хотя бы одна из добавленных вами заметок содержит текст, посвященный этой теме). Добавление поля запроса
  5. В статусе может отобразиться ошибка. Произошла ошибка.
  6. Это связано с отсутствием индекса. Чтобы настроить параметры отсутствующего индекса, перейдите в консоль Google Cloud для вашего проекта по этой ссылке , а затем выберите свой проект из списка. Выбор правильного проекта
  7. В Cloud Log Explorer теперь должно отображаться сообщение об ошибке "FAILED_PRECONDITION: Отсутствует конфигурация векторного индекса. Пожалуйста, создайте необходимый индекс с помощью следующей команды gcloud: ..." Сообщение об ошибке в обозревателе журналов.
  8. В сообщении об ошибке также содержится команда gcloud , которую необходимо выполнить для настройки отсутствующего индекса.
  9. Выполните следующую команду в командной строке. Если у вас не установлен интерфейс командной строки gcloud , следуйте инструкциям по его установке, приведенным здесь .
    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
    
    Создание индекса занимает несколько минут. Вы можете отслеживать ход выполнения на вкладке «Индексы» в разделе Firestore консоли Firebase. Статус нового индекса
  10. После создания индекса можно создать новый документ запроса.
  11. Теперь в поле результатов должен отобразиться список совпадающих идентификаторов документов. Результат выполнения семантического запроса
  12. Скопируйте один из этих идентификаторов и вернитесь к коллекции notes .
  13. Используйте сочетание клавиш ⌘+F для поиска скопированного вами идентификатора документа — это документ, который наилучшим образом соответствует вашему запросу. Поиск идентификатора документа в списке документов.

7. Реализовать семантический поиск.

Наконец-то пришло время подключить ваше мобильное приложение к расширению Vector Search with Firestore и реализовать функцию семантического поиска, которая позволит пользователям искать в своих заметках, используя запросы на естественном языке.

Подключите вызываемую функцию для выполнения запросов.

Расширение Vector Search with Firestore включает в себя облачную функцию, которую можно вызывать из мобильного приложения для запроса к индексу, созданному ранее в этом практическом занятии. На этом шаге вы установите связь между вашим мобильным приложением и этой вызываемой функцией. SDK Firebase для Swift включает API, которые упрощают вызов удаленных функций.

  1. Вернитесь в Xcode и убедитесь, что вы находитесь в проекте, который клонировали на предыдущем шаге этого практического занятия.
  2. Откройте файл NotesRepository.swift .
  3. Найдите строку, содержащую private lazy var vectorSearchQueryCallable: Callable = functions.httpsCallable("")

Для вызова облачной функции необходимо указать имя функции, которую вы хотите вызвать.

  1. Перейдите в консоль Firebase для вашего проекта и откройте пункт меню «Функции» в разделе «Сборка» .
  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. Вызовите вызываемую функцию, используя метод `callable`.
    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 []
      }
    }
    

Подключите пользовательский интерфейс

Чтобы пользователи могли искать свои заметки, вам потребуется реализовать строку поиска на экране списка заметок. Когда пользователь вводит поисковый запрос, необходимо вызвать метод performQuery реализованный на предыдущем шаге. Благодаря модификаторам searchable и task view, предоставляемым SwiftUI, это потребует всего несколько строк кода.

  1. Сначала откройте NotesListScreen.swift
  2. Чтобы добавить поле поиска в список, добавьте модификатор представления .searchable(text: $searchTerm, prompt: "Search") непосредственно перед строкой ` .navigationTitle("Notes")
  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. В этом практическом задании вы должны увидеть те же заметки, которые вы добавили в приложение ранее, а также любые заметки, добавленные через консоль Firebase.
  3. В верхней части списка заметок вы должны увидеть поле поиска.
  4. Введите термин, который встречается в одном из добавленных вами документов. Опять же, это лучше всего подходит для семантических запросов, например: «Как вызвать асинхронные API Firebase из Swift?» (при условии, что хотя бы одна из добавленных вами заметок содержит текст, посвященный этой теме).
  5. Вероятно, вы ожидали увидеть результаты поиска, но вместо этого список пуст, а в консоли Xcode отображается сообщение об ошибке: «Функция была вызвана с недопустимым аргументом».

Приложение «Заметки» с пустым списком результатов.

Это означает, что вы отправили данные в неправильном формате.

Проанализируйте сообщение об ошибке.

  1. Чтобы выяснить, в чем проблема, перейдите в консоль Firebase.
  2. Перейдите в раздел «Функции» .
  3. Найдите функцию ext-firestore-vector-search-queryCallable , откройте меню переполнения, щелкнув по трем вертикальным точкам.
  4. Выберите «Просмотреть журналы» , чтобы перейти в обозреватель журналов.
  5. Вы должны увидеть ошибку.
Unhandled error ZodError: [
  {
    "code": "invalid_type",
    "expected": "object",
    "received": "string",
    "path": [],
    "message": "Expected object, received string"
  }
]

Это означает, что вы отправили данные в неправильном формате.

Используйте правильные типы данных.

Чтобы узнать, в каком формате расширение ожидает получать параметры, ознакомьтесь с документацией расширения.

  1. Перейдите в раздел «Расширения» в консоли Firebase.
  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 возвращает идентификаторы документов, которые могут принадлежать другому пользователю. Чтобы предотвратить это, нам необходимо использовать предварительный фильтр .

В 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)

Это позволит предварительно отфильтровать данные на основе идентификатора вошедшего в систему пользователя. Как и следовало ожидать, для этого необходимо обновить индекс Firestore.

Выполните следующую команду в командной строке, чтобы определить новый индекс Firestore, который будет включать как идентификатор userId , так и векторные представления (vector embeddings) в поле embedding .

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. Поздравляем!

Поздравляем с успешным завершением этого практического занятия!

В этом практическом занятии вы научились:

  • Настройте базу данных Cloud Firestore с включенным семантическим поиском.
  • Создайте простое приложение SwiftUI для взаимодействия с базой данных.
  • Реализуйте строку поиска, используя модификаторы `searchable view` и `task` из SwiftUI.
  • Вызовите облачную функцию для выполнения семантического поиска в базе данных, используя интерфейс Callable из Firestore SDK.

Благодаря знаниям, полученным в этом практическом занятии, вы теперь можете создавать мощные приложения, использующие возможности семантического поиска Cloud Firestore, чтобы предоставить пользователям более интуитивно понятный и эффективный поиск.

Чтобы узнать больше о новом векторном поле Firestore и о том, как вычислять векторные представления, ознакомьтесь с документацией .