提升多值领域

时间:2009-10-29 17:06:38

标签: lucene lucene.net

我有一组文件,其中包含我要编制索引的评分项目。我们的数据结构如下:

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中是否有允许此功能的机制?我宁愿不创建另一个索引只是为了解释这一点 - 感觉应该有一种方法使用单个索引。如果没有办法实现这一目标,我们必须补偿的一些想法是:

  1. 按降序值的顺序插入多值字段项。然后以某种方式添加位置感知分析,为该领域的第一个项目分配更高的提升/分数。
  2. 向该字段多次添加高分值。因此,分数== 1的RelatedScore可能会被添加三次,而一个分数==。3的RelatedScore只会被添加一次。
  3. 这些都会导致这些领域失去搜索保真度,是的,但它们可能已经足够好了。有什么想法吗?

2 个答案:

答案 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));
  }
}