Как выполнить поиск по шаблону в Lucene - PullRequest
2 голосов
/ 21 апреля 2011

Я знаю, что Lucene имеет обширную поддержку поиска по шаблону, и я знаю, что вы можете искать такие вещи, как:

Stackover * (который вернет Stackoverflow )

Тем не менее, мои пользователи не заинтересованы в изучении синтаксиса запросов. Может ли Lucene выполнить этот тип поиска по шаблону с помощью встроенного анализатора? Или я должен добавить "*" к каждому поисковому запросу?

Ответы [ 3 ]

3 голосов
/ 21 апреля 2011

Делать это с помощью строковых манипуляций довольно сложно, особенно если учесть, что QueryParser поддерживает повышение, фразы и т. Д.

Вы можете использовать QueryVisitor, который переписывает TermQuery в PrefixQuery.

public class PrefixRewriter : QueryVisitor {
    protected override Query VisitTermQuery(TermQuery query) {
        var term = query.GetTerm();
        var newQuery = new PrefixQuery(term);
        return CopyBoost(query, newQuery);
    }
}

Класс QueryVisitor можно найти по адресу QueryVisitor для Lucene .

Обновление несколько лет спустя:

В блоге уже давно 404время назад, но источник все еще живет!В настоящее время его можно найти на github .

3 голосов
/ 24 апреля 2011

Если вы планируете превратить каждый запрос в шаблон, я бы задал себе следующие вопросы:

  1. Является ли Lucene лучшим инструментом для работы? по умолчанию подстановочные знаки переписываются на запросы с постоянным счетом, что означает, что вы полностью отбрасываете рейтинг релевантности и больше не «ищите», а вместо этого «сопоставляете». Возможно, для вашего приложения библиотека поисковой системы - не лучшее решение, и другой инструмент (например, база данных) был бы лучше.
  2. Если ответ на вопрос № 1 все еще «да», то я бы порекомендовал взглянуть на то, какую именно проблему релевантности вы пытаетесь решить. Например, если вы хотите, чтобы запросы соответствовали составным или основанным на словах словам, вместо этого, возможно, вместо этого добавьте декомпоундер или основатель в цепочку анализа. Вы также можете рассмотреть возможность использования техники индексации n-грамм в качестве другой альтернативы.
0 голосов
/ 21 апреля 2011

Если я хочу сделать что-то подобное, я обычно форматирую термин перед поиском, например,

searchTerm = QueryParser.EscapesearchTerm);
if(!searchTerm.EndsWith(" "))
{
    searchTerm = string.Format("{0}*", searchTerm);
}

, который будет экранировать любые специальные символы, введенные людьми. и если термин не заканчивается пробелом, добавляется * в конце. Поскольку * само по себе вызовет исключение синтаксического анализа.

...