@suulisin вы правы, я не читал это внимательно, потому что мне хотелось поделиться тем, что я нашел. Спасибо за ваши усилия, чтобы указать на это, и я буду более осторожным

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

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

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

 Albert Renshaw09 окт. 2018 г., 09:34
Firebase теперь поддерживает это. Пожалуйста, обновите ответ:stackoverflow.com/a/52715590/2057171
 suulisin24 нояб. 2017 г., 11:06
Пожалуйста, вы нашли какое-либо решение. я искал несколько дней что-то подобное без недостатка

Ответы на вопрос(5)

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

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

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

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

Использование:
collection("collectionPath").
    where("searchTermsArray", "array-contains", "term").get()
 Yulian24 окт. 2018 г., 17:49
Это хорошее решение. Однако, поправьте меня, если я ошибаюсь, но я думаю, что это не позволяет вам делать то, о чем просил @tehfailsafe. Например. если вы хотите получить все имена, содержащие строку «abc», вы не добьетесь успеха с массивом-содержит, поскольку он будет возвращать только те документы, которые имеют точное имя «abc», но «abcD» или « 0abc "будет вне.
 Albert Renshaw25 окт. 2018 г., 11:05
@Yulian Да, я понял. Firebase - это NoSQL, хотя он действительно хорош для быстрого и эффективного выполнения этих типов операций, даже если они могут быть ограничены для некоторых проблем, выходящих за рамки области поиска, таких как поиск по шаблону.
 sfratini01 нояб. 2018 г., 16:46
Ну, вы могли бы создать отдельное поле для каждого с представлением слов, разделенных как titleArray: ['this', 'is', 'a', 'title'] каждый раз, когда вы обновляете документ. И тогда поиск будет основан на этом поле, а не на заголовке. Вы должны создать triiger onUpdate для создания этих полей. Много работы для текста, основанного на поиске, но у меня скорее есть улучшения производительности NoSQL.
 Albert Renshaw24 окт. 2018 г., 20:29
@Yulian В мире программированияSearch term обычно подразумевается целый термин, разделенный пробелом, пунктуацией и т. д. с обеих сторон. Если вы гуглитеabcde сейчас вы найдете результаты только для таких вещей, как%20abcde. или же,abcde! но нетabcdefghijk.., хотя, конечно, весь набранный алфавит встречается в Интернете гораздо чаще, поиск не для abcde *, а для изолированного abcde
 Yulian25 окт. 2018 г., 10:48
Я понимаю вашу точку зрения, и я согласен с этим, но я, вероятно, был введен в заблуждение словом'contains', что означает именно то, что я имею в виду во многих языках программирования. То же самое касается'%searchTerm%' с точки зрения SQL.
Решение Вопроса

==, <, <=, >, >=.

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

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

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

 tehfailsafe04 окт. 2017 г., 18:14
Это не совсем то, что я ищу. У меня большой список продуктов с длинными названиями. "Rebok Mens Tennis Racket". Пользователь может искатьtennis, но в зависимости от доступных операторов запроса нет возможности получить эти результаты. Объединяя>= а также<= не работает. Конечно, я могу использовать Algolia, но я мог бы также использовать его с Firebase для выполнения большинства запросов и не нужно переключаться на Firestore ...
 Kuba12 июл. 2018 г., 21:51
@ A.Chakroun, что именно грубо в моем ответе?
 tehfailsafe04 окт. 2017 г., 18:31
Ах, тогда ваш "фильтр по префиксам" был красной селедкой. То, как вы это заявили, подразумевало, что это может сработать для моего варианта использования, что заставило меня подумать, что я недостаточно хорошо объяснил сценарий.
 Kuba04 окт. 2017 г., 18:37
@tehfailsafe Я немного изменил формулировку (я имел в виду, что вы можететолько фильтр по префиксам), надеюсь, теперь все стало понятнее!
 Kuba04 окт. 2017 г., 18:24
@tehfailsafe Ну, ваш вопрос «как запросить, если поле содержит строку», а ответ «вы не можете этого сделать».

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

Сторонние поисковые решения, такие какAlgolia а такжеЭластичный поиск рекомендуются

 Daniel Rodriguez22 сент. 2018 г., 18:19
проблема в том, что это не бесплатно
 briznad24 янв. 2019 г., 02:53
Это правильный ответ на поставленный вопрос и должен быть принят как лучший.
 tehfailsafe08 февр. 2018 г., 20:11
Я прочитал документы, хотя это не идеально. Недостаток в том, что у Algolia и Firestore разные модели ценообразования ... Я могу с радостью иметь 600 000 документов в Firestore (если я не запрашиваю слишком много в день). Когда я отправляю их в Алголию для поиска, я теперь должен платить Алголии 310 долларов в месяц, чтобы иметь возможность выполнять поиск по названию в моих документах Firestore.

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

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

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

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

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

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

Вы, вероятно, все еще лучше с подвеснымполнотекстовый поиск.

 Henry15 окт. 2017 г., 11:26
Можно ли использовать облачную функцию сcloud.google.com/appengine/docs/standard/java/search?
 Gil Gilbert16 окт. 2017 г., 04:16
Если вы спросите это как продолжение этого ответа, то: Полнотекстовый поиск в AppEngine полностью отделен от Firestore, и это не поможет вам напрямую. Вы можете реплицировать свои данные, используя облачную функцию, но это по сути то, что предлагает использовать внешний полнотекстовый поиск. Если вы спрашиваете что-то еще, пожалуйста, начните новый вопрос.
 Husam02 янв. 2018 г., 22:21
В Firestore, вам необходимо проиндексировать все термины перед использованиемwhere
 Slawoj05 апр. 2018 г., 11:42
@epeleg Запрос будет работать после того, как вы создадите для него индекс, но невозможно создать индекс для каждого возможного термина, содержащегося в названии вашего продукта, поэтому для текстового поиска терминов в названиях продуктов этот подход не работал для моего случая.
 Slawoj14 янв. 2018 г., 12:34
Как отметил Хусам, все эти поля должны быть проиндексированы. Я хотел включить поиск по любому термину, который содержит название моего продукта. Поэтому я создал свойство типа «объект» в своем документе, ключи которого являются частями имени продукта, каждому из которых присвоено значение «true», в надежде, что поиск по адресу («nameSegments.tennis», «==», true) будет работать, но FireStore предлагает создать индекс для nameSegments.tennis, то же самое для любого другого термина. Поскольку может быть бесконечное количество терминов, этот ответ пригоден только для очень ограниченного сценария, когда все поисковые термины определены заранее.

чтобы распечатать значение строки. Это должно работать:

where('name', '==', `${searchTerm}`)
 tehfailsafe09 нояб. 2017 г., 18:25
Спасибо, но этот вопрос касается получения неточных значений. Например, рассматриваемый пример действительно работает, если имя точное. Если у меня есть документ с именем: «Тест», а затем я ищу «Тест», это работает. Но я ожидал, что смогу искать «tes» или «est» и все же получить результат «Test». Представьте себе вариант использования с названиями книг. Люди часто ищут частичные названия книг, а не точное название целиком.
 suulisin24 нояб. 2017 г., 11:10
Вы читали вопрос вообще.
 Zach J30 мар. 2018 г., 16:18
@suulisin вы правы, я не читал это внимательно, потому что мне хотелось поделиться тем, что я нашел. Спасибо за ваши усилия, чтобы указать на это, и я буду более осторожным

Ваш ответ на вопрос