C# 使用在Lucene.Net中不起作用的特殊字符字符串搜索记录

C# 使用在Lucene.Net中不起作用的特殊字符字符串搜索记录,c#,.net,lucene,lucene.net,C#,.net,Lucene,Lucene.net,我是Lucene的新手,在这里我面临着lecene搜索的严重问题。当使用字符串/带数字的字符串搜索记录时,它工作正常。但是,当使用带有特殊字符的字符串搜索记录时,它不会产生任何结果 ex: example - Brings results 'examples' - no result %example% - no result example2 - Brings results @example - no results 代码: 索引 _document.

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

谁能帮我解决这个问题。

看来还有工作要做。我强烈要求你准备一本关于Lucene的入门书,比如《Lucene在行动》第二版(因为你正在使用版本3)。尽管它以Java为目标,但Java示例很容易适应C#,而且实际上概念才是最重要的

首先,这是:

“*”+searchParams.SearchForText+“*”

不要那样做。前导通配符搜索效率极低,会在一个相当大的索引上消耗大量资源,前导通配符搜索和尾随通配符搜索的效率加倍-如果查询文本是
*e*
,会发生什么情况

这似乎比发布的代码中显示的还要多,因为没有理由不根据输入获得点击率。下面的代码段将在控制台中生成以下内容:

索引项:
示例
例2

原始文本%example%作为查询文本:example得到1次点击
原始文本“示例”作为查询文本:示例命中1次
原始文本示例作为查询文本:示例获得1次点击
原始文本@example作为查询文本: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
                );
        }
    }
}
publicstaticvoid示例()
{
变量字段_name=“text”;
var field_value=“%example%'example'example@example-example”;
var字段_value2=“example2”;
var luceneVer=Lucene.Net.Util.Version.Lucene_30;
使用(var writer=new IndexWriter(new RAMDirectory(),
新的StandardAnalyzer(luceneVer),IndexWriter.MaxFieldLength.UNLIMITED)
)
{
var doc=新文档();
变量字段=新字段(
字段名称,
字段u值,
Field.Store.YES,
Field.Index.analysis,
Field.TermVector.YES
);
单据新增(字段);
writer.AddDocument(doc);
doc=新文档();
字段=新字段(
字段名称,
字段_值2,
Field.Store.YES,
Field.Index.analysis,
Field.TermVector.YES
);
单据新增(字段);
writer.AddDocument(doc);
writer.Commit();
Console.WriteLine();
//显示索引中的所有术语。
使用(var reader=writer.GetReader())
{
TermEnum terms=reader.terms();
Console.WriteLine(“索引项:”);
while(terms.Next())
{
Console.WriteLine(“\t{0}”,terms.Term.Text);
}
}
//搜索原始内容@field\u value中的每个单词
使用(var searcher=newindexsearcher(writer.GetReader()))
{
字符串查询;
QueryParser解析器;
查询;
TopDocs TopDocs;
列表字段_查询=新列表(字段_值.Split(“”));
字段\查询。添加(字段\值2);
var分析仪=新的标准分析仪(luceneVer);
while(field_.Count>0)
{
查询\文本=字段\查询[0];
parser=newqueryparser(luceneVer,字段名称,分析器);
query=parser.Parse(查询文本);
topDocs=searcher.Search(查询,空,100);
Console.WriteLine();
WriteLine(“原始文本{0}作为查询{1}得到{2}命中率)”,
查询文本,
查询
topDocs.TotalHits
);
字段_查询。删除(0);
}
//现在执行通配符查询“示例*”
query_text=“example*”;
parser=newqueryparser(luceneVer,字段名称,分析器);
query=parser.Parse(查询文本);
topDocs=searcher.Search(查询,空,100);
Console.WriteLine();
WriteLine(“通配符原始文本{0}作为查询{1}得到{2}命中率)”,
查询文本,
查询
topDocs.TotalHits
);
}
}
}

如果需要执行精确匹配,并为某些字符(如%)编制索引,则需要使用除
StandardAnalyzer
之外的其他工具,可能是自定义分析器。

这很混乱,查询文本
“*”+searchParams.SearchForText+“*”
应该抛出一个
ParseException
,因为查询以通配符开头。为什么要执行通配符搜索?