[英]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.