我使用Royal Mail的示例PAF文件,此数据已导入数据库,并且通过我自己的Lucene索引器控制台应用程序对以下字段进行了索引:
...
var doc = new Document();
doc.Add(new Field("id", item.Id.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
doc.Add(new Field("postcode", item.Postcode, Field.Store.YES, Field.Index.ANALYZED));
doc.Add(new Field("buildingname", item.BuildingName, Field.Store.YES, Field.Index.ANALYZED));
...
我现在想要做的是,提供部分或完整的邮政编码或建筑物名称,并返回匹配项,只要在每个文档的邮政编码或建筑物名称字段中松散地存在一个搜索词。因此,如果邮政编码/建筑物名称为:
TE55 5TT测试大楼
如果我提供了“ TE55测试”,我希望它会回来。
我的搜索代码
var fieldsToAnalyse = new[] { "postcode", "buildingname" };
var finalQuery = new BooleanQuery();
var parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_29, fieldsToAnalyse, _analyzer);
string[] terms = searchTerm.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
foreach (string term in terms)
{
var formattedTerm = term.Replace("~", "");
var formattedTermWildcard = $"+{formattedTerm}~";
finalQuery.Add(parser.Parse(formattedTermWildcard), Occur.MUST);
}
var searcher = new IndexSearcher(_indexDirectory, true);
var hits = searcher.Search(finalQuery,10);
foreach (var hit in hits.ScoreDocs)
{
documents.Add(searcher.Doc(hit.Doc));
}
_analyzer.Close();
searcher.Dispose();
return documents;
实际发生的事情。
finalQuery
的值为:
{+(+(邮政编码:test〜0.5建筑名称:test〜0.5))+(+(邮政编码:te55〜0.5 建筑物名称:te55〜0.5))}
我得到的邮编中包含“ te55”但buildingname
为空的地址。我需要它的邮政编码都包含“ te55”,而建筑物名称中包含单词“ test”。
边注
如果我仅提供一个搜索字词,则会得到:
System.IndexOutOfRangeException:'索引超出了 数组。”
谁也在难过我
答案 0 :(得分:1)
我建议您以编程方式(而不是通过解析)创建查询,并且从字符串版本中我也可以看到您的子句都是应该的(在它们周围没有符号)。
提醒一下-Lucene布尔语法如下:
+ must clause
<empty> should clause
- not clause
如果您有,
postcode:te55~0.5 buildingname:te55~0.5
要求匹配至少一个,但不强制两者。
您需要这样的查询:
+postcode:te55~0.5 +buildingname:te55~0.5
MultiFieldQueryParser
中的潜在问题是,默认情况下,它制作了should子句。您需要先setDefaultOperator(AND_OPERATOR)
,然后才能获得想要的行为。
一些与Lucene.Net 3.0.3相关的信息-https://lucenenet.apache.org/docs/3.0.3/d6/d0b/class_lucene_1_1_net_1_1_query_parsers_1_1_multi_field_query_parser.html