Как использовать поиск по тексту

Используйте функции текстового поиска в Cloud Firestore, чтобы искать определенные строки в коллекции.

Подготовка

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

  1. Убедитесь, что у вас есть доступ к существующей базе данных операций, совместимой с MongoDB, или создайте базу данных и подключитесь к ней.

  2. Убедитесь, что у вас есть текстовый индекс, или создайте его.

В текстовых запросах используется оператор $text. Укажите строку запроса в аргументе $search.

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

  # Find search
  db.cities.find({ $text: { $search: "french bread" } })

  # Aggregation search
  db.cities.aggregate([
    { $match: { $text: { $search: "french bread" } } }
  ]);

Если индекс разделен, вы можете отфильтровать результаты по разделу, включив его в фильтр равенства "и" в поиске. Например, если у вас есть раздел city, вы можете отфильтровать текстовый поиск следующим образом:

db.myCollection.find( { $and: [
  { $text: { $search: "french bread" } },
  { "city": "Paris" }
] } )

Вы также можете отфильтровать агрегированные данные по сегменту. Пример:

db.myCollection.aggregate([
 { $match: { $text: { $search: "french bread" } } },
 { "city": "Paris" }
] );

Значение раздела должно быть строкой. Фильтр разделов должен быть соединен с текстовым поиском с помощью оператора "and".

Как настроить язык текстового поиска

Вы можете задать язык текстового поиска с помощью аргумента $language. Пример:

  db.cities.find({ $text: { $search: "french bread", $language: "en"} })

Если язык не задан, то при поиске используется язык текстового индекса.

Поиск точного совпадения

Чтобы найти точное совпадение, заключите поисковый запрос в кавычки. Пример:

  # Find search
  db.cities.find({ $text: { $search: "\"best french bread\"" } })

  # Aggregation search
  db.cities.aggregate([
    { $match: { $text: { $search: "\"best french bread\"" } } },
  ]);

Как выполнить поиск по комбинации слов

Чтобы сделать текстовый поиск более точным, укажите цепочку терминов. Например, следующий запрос вернет документы, соответствующие комбинации best AND french AND ("bread" OR "is"):

  # Find search
  db.cities.find({ $text: { $search: "\"best\" \"french\" bread is" } })

  # Aggregation search
  db.cities.aggregate([
    { $match: { $text: { $search: "\"best\" \"french\" bread is" } } },
  ]);

Исключить слово

Чтобы исключить слово из текстового поиска, добавьте перед ним дефис (-):

  # Find search
  db.cities.find({ $text: { $search: "best bread -french"} })

  # Aggregation search
  db.cities.aggregate([
    { $match: { $text: { $search: "best bread -french" } } },
  ]);

Рассчитать показатель релевантности

Используйте выражение {$meta: "textScore"}, чтобы рассчитать показатель релевантности документов, соответствующих текстовому поиску. Чтобы отсортировать результаты по убыванию, используйте в выражении сортировки $meta. Рассмотрим следующие примеры, где SCORE_FIELD – это название поля, используемого для хранения значения оценки:

  # Find search
  db.cities
    .find({ $text: { $search: "best french bread" } })
    .sort({ SCORE_FIELD: { $meta: "textScore" } })

  # Aggregation search
  db.cities.aggregate([
    { $match: { $text: { $search: "best french bread" } } },
    { $sort: { "SCORE_FIELD": { $meta: "textScore"} } },
  ]);

Вы также можете использовать текстовую оценку в выражениях проекции. Пример:

  # Find search
  db.cities
    .find({ $text: { $search: "best french bread" } })
    .project({ score: { $meta: "textScore" } })

  # Aggregation search
  db.cities.aggregate([
    { $match: { $text: { $search: "best french bread" } } },
    { $project: { "scoreField": { $meta: "textScore"} } },
  ]);

Чтобы повысить релевантность результатов текстового поиска, оператор $text дополняет строку поиска в соответствии с указанным языком, включая совпадения для контекстно-зависимых синонимов, форм с основой, исправленных терминов, диакритических вариантов и т. д.

Ограничения

  • Операторы $near и $text нельзя использовать в одном текстовом поиске.
  • В одном поисковом запросе find или aggregation можно использовать только один оператор $text.
  • В агрегированных данных этап $match с $text должен быть первым этапом конвейера.
  • Тег $text может быть вложен только в теги $and и $or.
  • Если $text находится внутри $or, дизъюнкты, не связанные с поиском, могут использовать существующие упорядоченные индексы для оптимизации поиска. Если другие дизъюнкты не индексируются, то поиск выполняется путем сканирования коллекции.
  • $text нельзя использовать с подсказками.
  • Запросы с текстовым поиском нельзя сортировать по полю $natural.