Lucene.Net 跨文档中存在的多个字段搜索多个术语
Lucene.Net search for multiple terms accross multiple fields that exist in document
我正在使用 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));
...
我现在想做的是提供部分或完整的邮政编码或建筑物名称,并获取匹配项,只要每个文档的邮政编码或建筑物名称字段中存在松散的搜索词即可。所以如果 postcode/buildingname 是:
TE55 5TT Test Building
如果我提供 "TE55 Test" 我希望它能回来。
我的搜索码
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
的值为:
{+(+(postcode:test~0.5 buildingname:test~0.5)) +(+(postcode:te55~0.5
buildingname:te55~0.5))}
我收到的地址的邮政编码包含 "te55",但 buildingname
为空。我需要它有一个包含 "te55" 的邮政编码和包含单词 "test".
的建筑物名称
旁注
如果我只提供一个搜索词,我得到:
System.IndexOutOfRangeException: 'Index was outside the bounds of the
array.'
这也难倒我了
我建议以编程方式创建查询(而不是通过解析),而且从字符串版本我可以看到你的子句都是应该的(没有迹象表明它们)。
提醒 - 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
的一些相关信息
我正在使用 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));
...
我现在想做的是提供部分或完整的邮政编码或建筑物名称,并获取匹配项,只要每个文档的邮政编码或建筑物名称字段中存在松散的搜索词即可。所以如果 postcode/buildingname 是:
TE55 5TT Test Building
如果我提供 "TE55 Test" 我希望它能回来。
我的搜索码
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
的值为:
{+(+(postcode:test~0.5 buildingname:test~0.5)) +(+(postcode:te55~0.5 buildingname:te55~0.5))}
我收到的地址的邮政编码包含 "te55",但 buildingname
为空。我需要它有一个包含 "te55" 的邮政编码和包含单词 "test".
旁注
如果我只提供一个搜索词,我得到:
System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'
这也难倒我了
我建议以编程方式创建查询(而不是通过解析),而且从字符串版本我可以看到你的子句都是应该的(没有迹象表明它们)。
提醒 - 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
的一些相关信息