我有一组文件,其中包含我要编制索引的评分项目。我们的数据结构如下:
Document
ID
Text
List<RelatedScore>
RelatedScore
ID
Score
我的第一个想法是使用字段的Boost属性将每个RelatedScore添加为多值字段,以便在搜索时修改特定分数的值。
foreach (var relatedScore in document.RelatedScores) {
var field = new Field("RelatedScore", relatedScore.ID,
Field.Store.YES, Field.Index.UN_TOKENIZED);
field.SetBoost(relatedScore.Score);
luceneDoc.Add(field);
}
但是,似乎计算的“Norm”适用于整个多字段 - 文档的所有RelatedScore“值最终都会得到相同的分数。
Lucene中是否有允许此功能的机制?我宁愿不创建另一个索引只是为了解释这一点 - 感觉应该有一种方法使用单个索引。如果没有办法实现这一目标,我们必须补偿的一些想法是:
这些都会导致这些领域失去搜索保真度,是的,但它们可能已经足够好了。有什么想法吗?
答案 0 :(得分:3)
这似乎是Payloads的一个用例。我不确定这是否在Lucene.NET中可用,因为我只使用了Java版本。
另一种执行此操作的方法是,如果分数的绝对值不重要,则将它们离散化(根据值将它们置于存储桶中)并为每个存储桶创建一个字段。因此,如果您的得分范围为1到100,请创建10个称为RelatedScore0_10,RelatedScore10_20等的存储桶,对于该存储桶中包含RelatedScore的任何文档,请在该字段中添加“true”值。然后对于每个在OR查询上执行的搜索,例如:
(RelatedScore0_10:true^1 RelatedScore10_20:true^2 ...)
关于这一点的好处是你可以动态调整每个桶的增强值。否则,您需要重新索引以更改每个字段的字段范数(boost)值。
答案 1 :(得分:0)
如果您使用Lucene.Net,则可能还没有有效负载功能。你可以做的是将0-100相关性得分从1-10转换为一个桶(整数除以10),然后多次添加每个索引值(但只存储一次值)。然后,如果您搜索该字段,则lucene内置评分将考虑索引字段的频率(将根据相关性将其索引1-10次)。因此,结果可以通过变量相关性来排序。
foreach (var relatedScore in document.RelatedScores) {
// get bucket for relevance...
int bucket=relatedScore.Score / 10;
var field = new Field("RelatedScore", relatedScore.ID,
Field.Store.YES, Field.Index.UN_TOKENIZED);
luceneDoc.Add(field);
// add more instances of field but only store the first one above...
for(int i=0;i<bucket;i++)
{
luceneDoc.Add(new Field("RelatedScore", relatedScore.ID,
Field.Store.NO, Field.Index.UN_TOKENIZED));
}
}