C# 使用在Lucene.Net中不起作用的特殊字符字符串搜索记录
我是Lucene的新手,在这里我面临着lecene搜索的严重问题。当使用字符串/带数字的字符串搜索记录时,它工作正常。但是,当使用带有特殊字符的字符串搜索记录时,它不会产生任何结果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.
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
,因为查询以通配符开头。为什么要执行通配符搜索?