Поиск записей с использованием строки со специальными символами не работает в Lucene.Net - PullRequest
0 голосов
/ 20 марта 2020

Я новичок в Lucene, здесь я столкнулся с серьезными проблемами с поиском lecene. При поиске записей с использованием строки / строки с числами все работает нормально. Но это не дает никаких результатов при поиске записей с использованием строки со специальными символами.

ex: example - Brings results 
    'examples' - no result
    %example% - no result
    example2 - Brings results 
    @example - no  results

код:

Индексирование;

_document.Add(new Field(dc.ColumnName, dr[dc.ColumnName].ToString(), Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES));

Поисковый запрос:

Lucene.Net.Store.Directory _dir = Lucene.Net.Store.FSDirectory.Open(Config.Get(directoryPath));
Lucene.Net.Analysis.Analyzer analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30);

Query querySearch = queryParser.Parse("*" + searchParams.SearchForText + "*");
booleanQuery.Add(querySearch, Occur.MUST);

Может кто-нибудь помочь мне это исправить.

1 Ответ

0 голосов
/ 20 марта 2020

Кажется, есть работа, которую нужно сделать. Я призываю получить хорошую стартовую книгу по Lucene, такую ​​как Lucene in Action, второе издание (поскольку вы используете версию 3). Хотя он предназначен для Java примеров, он легко адаптируется к C#, и на самом деле наиболее важны концепции.

Во-первых, это:

"*" + searchParams.SearchForText + "*"

Не делай этого . Поиск с использованием подстановочных знаков крайне неэффективен и будет поглощать огромное количество ресурсов по значительному индексу, вдвойне для поиска с подстановочными символами в начале и в конце - что произойдет, если текст запроса будет *e*?

Похоже, что больше, чем показано в опубликованном коде, поскольку нет причин не получать хиты на основе входных данных. Ниже приведен фрагмент кода:

Ключевые слова: пример example2

необработанный текст% example% как текст запроса: пример получил 1 посещений необработанный текст «пример» как текст запроса: пример получил 1 хитов пример необработанного текста как текст запроса необработанный текст @example как текст запроса: пример получил 1 хитов необработанный текст example2 как текст запроса: example2 получил 1 посещений Пример необработанного текста с подстановочными символами * в качестве текста запроса: пример * получил 2 попаданий

См. Список Условия индекса ? НЕТ «специальных символов» в индексе, потому что StandardAnalyzer удаляет их во время индекса - при условии, что StandardAnalyzer используется для индексации поля?

Я рекомендую запустить фрагмент ниже в отладчике и наблюдать, что происходит .

public static void Example()
{
    var field_name = "text";
    var field_value = "%example% 'example' example @example example";
    var field_value2 = "example2";
    var luceneVer = Lucene.Net.Util.Version.LUCENE_30;

    using (var writer = new IndexWriter(new RAMDirectory(),
            new StandardAnalyzer(luceneVer), IndexWriter.MaxFieldLength.UNLIMITED)
            )
    {
        var doc = new Document();
        var field = new Field(
            field_name,
            field_value,
            Field.Store.YES,
            Field.Index.ANALYZED,
            Field.TermVector.YES
            );

        doc.Add(field);
        writer.AddDocument(doc);

        doc = new Document();
        field = new Field(
            field_name,
            field_value2,
            Field.Store.YES,
            Field.Index.ANALYZED,
            Field.TermVector.YES
            );

        doc.Add(field);
        writer.AddDocument(doc);
        writer.Commit();

        Console.WriteLine();
        // Show ALL terms in the index.
        using (var reader = writer.GetReader())
        {
            TermEnum terms = reader.Terms();
            Console.WriteLine("Index terms:");
            while (terms.Next())
            {
                Console.WriteLine("\t{0}", terms.Term.Text);
            }
        }

        // Search for each word in the original content @field_value
        using (var searcher = new IndexSearcher(writer.GetReader()))
        {
            string query_text;
            QueryParser parser;
            Query query;
            TopDocs topDocs;
            List<string> field_queries = new List<string>(field_value.Split(' '));
            field_queries.Add(field_value2);

            var analyzer = new StandardAnalyzer(luceneVer);
            while (field_queries.Count > 0)
            {
                query_text = field_queries[0];
                parser = new QueryParser(luceneVer, field_name, analyzer);
                query = parser.Parse(query_text);
                topDocs = searcher.Search(query, null, 100);
                Console.WriteLine();
                Console.WriteLine("raw text {0} as query {1} got {2} hit(s)",
                    query_text,
                    query,
                    topDocs.TotalHits
                    );
                field_queries.RemoveAt(0);
            }

            // Now do a wildcard query "example*"
            query_text = "example*";
            parser = new QueryParser(luceneVer, field_name, analyzer);
            query = parser.Parse(query_text);
            topDocs = searcher.Search(query, null, 100);
            Console.WriteLine();
            Console.WriteLine("Wildcard raw text {0} as query {1} got {2} hit(s)",
                query_text,
                query,
                topDocs.TotalHits
                );
        }
    }
}

Если вам необходимо выполнить точное сопоставление и индексировать определенные символы, такие как%, вам нужно использовать что-то отличное от StandardAnalyzer, возможно, специальный анализатор.

...