Правильная работа с запросом Lucene.Net

Рейтинг: 0Ответов: 1Опубликовано: 20.06.2023

Есть некоторый текст в котором мне нужно найти некоторые слова Для этого я пытаюсь использовать такой запрос

"C++" OR "Boost" OR "STLSoft" OR "STLPort" OR "C++ Templated Image Processing Library" ...

Запрос в целом работает верно, но по какой то причине в момент вызова QueryParser.Parse следующий запрос преобразуется в это: введите сюда описание изображения

У слова "C++" отбрасываются "++", из-за чего поиск происходит не верно. Как экранировать знак "+" в запросе? Так же, я заметил что при поиске через Lucene.Net, отбрасываются окончания. Как мне сделать так, чтобы запрос бы аналогичным методу Contains ignore case?

Ответы

▲ 2Принят

Скорее всего вы передаёте какой-нибудь SimpleAnalyzer или StandradAnalyzer в парсер запросов. Эти аналайзеры отбрасывают не буквенные символы при токенизации.

Из неотбрасывющих есть WhiteSpaceAnalyzer, но он регистрозависимый.

Вы можете реализовать аналайзер самостоятельно.

public class IgnoreCaseAnalyzer : Analyzer
{
    private readonly LuceneVersion matchVersion;

    public IgnoreCaseAnalyzer(LuceneVersion matchVersion)
    {
        this.matchVersion = matchVersion;
    }

    protected override TokenStreamComponents CreateComponents(string fieldName, TextReader reader)
    {
        return new TokenStreamComponents(new LowerCaseAnySymbolTokenizer(matchVersion, reader));
    }
}

public sealed class LowerCaseAnySymbolTokenizer : CharTokenizer
{
    public LowerCaseAnySymbolTokenizer(LuceneVersion matchVersion, TextReader @in)
        : base(matchVersion, @in) { }    

    public LowerCaseAnySymbolTokenizer(LuceneVersion matchVersion, AttributeFactory factory, TextReader @in)
        : base(matchVersion, factory, @in) { }

    protected override bool IsTokenChar(int c)
    {
        return !Character.IsWhiteSpace(c);
    }

    protected override int Normalize(int c)
    {
        return Character.ToLower(c, CultureInfo.InvariantCulture);
    }
}

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

Ещё может быть важно, что StandardAnalyzer умеет убирать стоп слова и обрезать через чур длинные токены. В некоторых датасетах это может положительно влиять на производительность и размер индекса. Вы можете расширить пример выше, если это актуально для вашего приложения.