Подтвердить что ты не робот

Google Firestore: запрос в подстроке значения свойства (текстовый поиск)

Я хочу добавить простое поле поиска, хотел бы использовать что-то вроде

collectionRef.where('name', 'contains', 'searchTerm')

Я пытался использовать where('name', '==', '%searchTerm%'), но ничего не возвращал.

4b9b3361

Ответ 1

Таких операторов нет, допустимыми являются ==, <, <=, >, >=.

Вы можете фильтровать только по префиксам, например, для всего, что начинается между bar и foo вы можете использовать

collectionRef.where('name', '>=', 'bar').where('name', '<=', 'foo')

Для этого вы можете использовать внешний сервис, такой как Algolia или ElasticSearch.

Ответ 2

В то время как ответ Кубы правдиво, насколько ограничиваются, вы можете частично эмулировать это с помощью подобной структуре:

{
  'terms': {
    'reebok': true,
    'mens': true,
    'tennis': true,
    'racket': true
  }
}

Теперь вы можете запросить с помощью

collectionRef.where('terms.tennis', '==', true)

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

Вы все еще можете обойти это, сохранив комбинации слов, но это становится ужасно быстрым.

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

Ответ 3

Firebase не поддерживает поиск термина внутри строки...

Firebase, однако, теперь поддерживает следующее, что решит для вашего случая и многих других:

По состоянию на август 2018 года они поддерживают запросы к array-contains. См.: https://firebase.googleblog.com/2018/08/better-arrays-in-cloud-firestore.html.

Теперь вы можете установить все ключевые термины в массив в виде поля, а затем запросить все документы, которые имеют массив, содержащий "X". Вы можете использовать логическое "И" для дальнейшего сравнения дополнительных запросов. (Это потому, что firebase в настоящее время не поддерживает составные запросы для множественных запросов, содержащих массив, поэтому сортировка запросов "И" должна выполняться на стороне клиента)

Использование массивов в этом стиле позволит оптимизировать их для одновременной записи, что приятно! Не проверял, поддерживает ли он пакетные запросы (документы не говорят), но я бы поспорил, что это так, поскольку это официальное решение.


Использование:

collection("collectionPath").
    where("searchTermsArray", "array-contains", "term").get()

Ответ 4

Согласно документам Firestore, Cloud Firestore не поддерживает собственную индексацию или поиск текстовых полей в документах. Кроме того, загрузка всей коллекции для поиска полей на стороне клиента нецелесообразна.

Рекомендуются сторонние поисковые решения, такие как Algolia и Elastic Search.

Ответ 5

Поздний ответ, но для тех, кто все еще ищет ответ, допустим, у нас есть коллекция пользователей, и в каждом документе коллекции у нас есть поле "имя пользователя", поэтому, если вы хотите найти документ, где имя пользователя начинается с "al" мы можем сделать что-то вроде

 FirebaseFirestore.getInstance().collection("users").whereGreaterThanOrEqualTo("username", "al")

Ответ 6

У меня была эта проблема, и я нашел довольно простое решение.

String search = "ca";
Firestore.instance.collection("categories").orderBy("name").where("name",isGreaterThanOrEqualTo: search).where("name",isLessThanOrEqualTo: search+"z")

IsGreaterThanOrEqualTo позволяет нам отфильтровывать начало нашего поиска и, добавляя "z" в конец isLessThanOrEqualTo, мы ограничиваем наш поиск, чтобы не переходить к следующим документам.

Ответ 7

Я на самом деле думаю, что лучшее решение сделать это в Firestore - это поместить все подстроки в массив и просто выполнить запрос array_contains. Это позволяет вам выполнять сопоставление подстроки. Немного излишне хранить все подстроки, но если ваши условия поиска короткие, это очень и очень разумно.

Ответ 8

Я согласен с ответом @Kuba, но, тем не менее, необходимо добавить небольшое изменение, чтобы оно идеально подходило для поиска по префиксу. вот что у меня сработало

Для поиска записей, начинающихся с имени queryText

collectionRef.where('name', '>=', queryText).where('name', '<=', queryText+ '\uf8ff').

Символ \uf8ff используемый в запросе, является очень высокой кодовой точкой в диапазоне Юникода (это код [PUA] Частной области использования). Поскольку это после большинства обычных символов в Unicode, запрос соответствует всем значениям, которые начинаются с queryText.

Ответ 10

Если вы не хотите использовать сторонние сервисы, такие как Algolia, Firebase Cloud Functions - отличная альтернатива. Вы можете создать функцию, которая может принимать входной параметр, обрабатывать записи на стороне сервера и затем возвращать те, которые соответствуют вашим критериям.

Ответ 11

Мы можем использовать обратную галочку, чтобы распечатать значение строки. Это должно работать:

where('name', '==', `${searchTerm}`)