Как запросить lucene с "похожим" оператором?

Подстановочный знак * может использоваться только в конце слова, например user*.

Я хочу запросить с помощью %user%, как это сделать?

Ответы

Ответ 1

Lucene предоставляет ReverseStringFilter, который позволяет вести поиск под общим шаблоном, например * user. Он работает путем индексирования всех членов в обратном порядке.

Но я думаю, что нет никакого способа сделать что-то похожее на "LIKE% user%".

Ответ 2

Проблема с запросами LIKE заключается в том, что они дорогие с точки зрения времени, затраченного на выполнение. Вы можете настроить QueryParser, чтобы разрешить основные подстановочные знаки со следующим:

QueryParser.setAllowLeadingWildcard(true)

И это позволит вам выполнять поиск, например:

*user*

Но это займет много времени. Иногда, когда люди говорят, что им нужен LIKE-запрос, они хотят fuzzy query. Это позволит вам выполнить следующий поиск:

user~

Что бы соответствовало условиям users и fuser. Вы можете указать расстояние редактирования между термином в вашем запросе и условиями, которые вы хотите согласовать, с использованием значения с плавающей запятой между 0 и 1. Например, user~0.8 будет соответствовать большему количеству терминов, чем user~0.5.

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

.*user.*

Ответ 3

Поскольку Lucene 2.1 вы можете использовать

QueryParser.setAllowLeadingWildcard(true);

но это может привести к снижению производительности. LuceneFAQ содержит дополнительную информацию для этого.

Ответ 4

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

Поисковые системы ключевых слов работают, создавая обратный индекс всех слов в корпусе, который сортируется по порядку слов. Когда вы выполняете обычный поиск без подстановочных знаков, двигатель использует тот факт, что записи индекса сортируются, чтобы найти запись или записи для вашего слова в шагах O(logN), где N - количество слов или записей. Для шаблона слова с шаблоном суффикса происходит то же самое, что и первое совпадающее слово, и другие совпадения обнаруживаются путем сканирования записей до тех пор, пока фиксированная часть шаблона больше не будет соответствовать.

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