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

MongoDB полнотекстовый поиск + обходной путь для частичного совпадения слов

Поскольку невозможно найти "голубику" словом "синий", используя полнотекстовый поиск mongodb, я хочу помочь моим пользователям заполнить слово "синий" на "черника". Чтобы сделать это, можно ли запросить все слова в полном текстовом индексе mongodb → , чтобы я мог использовать слова в качестве предложений, например, для typeahead.js?

4b9b3361

Ответ 1

Исключение языка в текстовом поиске использует алгоритм, чтобы попытаться связать слова, полученные из общей базы (например, "running" должен соответствовать "run" "). Это отличается от сочетания префикса (например, синего цвета, соответствующего" голубике"), которое вы хотите реализовать для функции автозаполнения.

Чтобы наиболее эффективно использовать typeahead.js с текстовым поиском MongoDB, я бы предложил сосредоточиться на поддержке prefetch в typeahead:

  • Создайте коллекцию keywords, в которой есть общие слова (возможно, с использованием частоты использования), используемые в вашей коллекции. Вы можете создать эту коллекцию с помощью запустите Map/Reduce в коллекции, в которой есть индекс поиска текста, и обновите список слов, используя периодическая Инкрементная карта/Уменьшить при добавлении новых документов.

  • Попросите ваше приложение сгенерировать JSON-документ из коллекции keywords с уникальными ключевыми словами (возможно, только с "популярными" ключевыми словами на основе частоты слов, чтобы сохранить список управляемым/релевантным).

Затем вы можете использовать сгенерированные ключевые слова JSON для автозаполнения на стороне клиента с помощью функции typeahead prefetch:

$('.mysearch .typeahead').typeahead({
  name: 'mysearch',
  prefetch: '/data/keywords.json'
});

typeahead.js будет кэшировать данные prefetch JSON в localStorage для поиска на стороне клиента. Когда форма поиска отправляется, ваше приложение может использовать серверный текстовый поиск MongoDB, чтобы вернуть полные результаты в порядке соответствия.

Ответ 2

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

Затем, когда вы выполняете запрос $search, вы просто снова разбиваете запрос на символы.

Обратите внимание, что это работает только для коротких строк, длина которых меньше 32, в противном случае процесс построения индексации займет очень много времени, поэтому при вставке новых записей производительность будет значительно ниже.

Ответ 3

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

Ответ 4

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

В зависимости от размера вашей коллекции и объема оперативной памяти, которую вы можете получить, вы можете выполнить поиск по $regex, создав соответствующий индекс. Например:

db.collection.find( {query : {$regex: /querywords/}}).sort({'criteria': -1}).limit(limit)

Вам понадобится индекс следующим образом:

db.collection.ensureIndex( { "query": 1, "criteria" : -1 } )

Это может быть очень быстро, если у вас достаточно памяти.

Надеюсь, что это поможет.

Ответ 5

Для тех, кто еще не начал внедрять какую-либо архитектуру базы данных и здесь для решения, перейдите к Elasticsearch. Его база данных, основанная на json-документе, похожа на mongodb структурно. У этого есть анализатор "edge-ngram", который действительно действительно эффективен и быстр в предоставлении вам, вы имели в виду поиски неправильной записи. Вы также можете искать частично.