#lucene #lucene.net #fuzzy-search
#lucene #lucene.net #нечеткий поиск
Вопрос:
В моем приложении у меня есть компания с полем названия This is a test
, которое правильно индексируется Lucene.Net. Для справки, для моего MultiFieldQueryParser
оператора по умолчанию установлено значение QueryParser.Operator.AND
.
Мой поиск завершается, когда я ищу this test~
и this tst~
. Однако мой поиск завершается неудачей, когда я пытаюсь выполнить поиск по this~ test~
, thas~ test~
, thas test~
и другим вариантам.
Вся цель состоит в том, чтобы позволить пользователю немного ошибиться в своем поиске, поэтому, если пользователь выполняет поиск по Jon Doe
, он все равно покажет результаты для John Doe
, позволяя пользователям не помнить точное написание того, что они ввели в базу данных. К сожалению, похоже, что он разрешает нечеткий поиск только по последнему термину в поисковой фразе. Я делаю что-то неправильно, или мне нужно использовать целый отдельный анализатор, чтобы сделать это?
Ответ №1:
Недавно мне пришлось реализовать нечто подобное в моем проекте.
В итоге я разделил фразу на несколько сегментов и построил запрос вручную.
var input = "This is a test";
var fieldName = "yourField";
var minimumSimilarity = 0.5f;
var prefixLength = 3;
var query = new BooleanQuery();
var segments = input.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries);
foreach (var segment in segments)
{
var term = new Term(fieldName, segment);
var fuzzyQuery = new FuzzyQuery(term, minimumSimilarity, prefixLength);
query.Add(fuzzyQuery, BooleanClause.Occur.SHOULD);
}
Я знаю, это очень примитивно, но, похоже, работает.
Примечание: это было протестировано только в Lucene.net v2.3.1.3
Комментарии:
1. Примечание: Это работает лучше всего, если вы используете анализатор пробелов во время индексации, многие другие анализаторы будут использовать данные в нижнем регистре, поэтому поиск по «Этому» ничего не соответствует.
2. В моем случае не требовалось, чтобы поиск учитывал регистр, поэтому я генерирую поиск
Term
с помощьюStandardAnalyzer.TokenStream(string fieldName, TextReader reader)
3. Для Java это будет
query.add(new BooleanClause(fuzzyQuery, Occur.SHOULD))
в последней строке