簡體   English   中英

使用帶有特殊字符的字符串搜索記錄在 Lucene.Net 中不起作用

[英]Searching records using string with special characters not working in Lucene.Net

我是 Lucene 的新手,在這里我面臨着 lecene search 的嚴重問題。 使用帶數字的字符串/字符串搜索記錄時,它工作正常。 但是當使用帶有特殊字符的字符串搜索記錄時,它不會帶來任何結果。

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);

誰能幫我解決這個問題。

看來有工作要做。 我強烈建議您購買一本關於 Lucene 的優秀入門書籍,例如Lucene in Action, Second Edition (因為您使用的是第 3 版)。 盡管它針對的是 Java 示例,但它們很容易適應 C#,而實際上概念才是最重要的。

首先,這個:

"*" + searchParams.SearchForText + "*"

不要那樣做 前導通配符搜索效率極低,並且會在相當大的索引上消耗大量資源,對於前導和尾隨通配符搜索會加倍 - 如果查詢文本是*e*會發生什么?

似乎還有比發布的代碼中顯示的更多的事情,因為沒有理由不根據輸入獲得點擊。 下面的代碼段將在控制台中生成以下內容:

索引詞:
例子
例子2

原始文本 %example% 作為查詢文本:示例獲得 1 次點擊
原始文本“示例”作為查詢文本:示例獲得 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其他東西,可能是自定義分析器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM