2016-03-09 55 views
1

我有以下要求的字段:在單個字段上禁用長度標準化?

  1. 它必須在索引時間被升壓,因此「omitNorms」必須保持「假」
  2. 但是,它必須不會受到字段長度歸一化(即。僅僅因爲一個術語在1:10的話對1發現:1000應該不會影響得分 - 兩者都應該是同等權重)

在至少一種其他領域,我其實想字段長度正常化,所以我不懷疑在搜索器上廣泛應用定製的相似性是適當的。

如何在索引時增加單個字段,但禁用字段長度規範化的效果?

回答

1

您可以使用PerFieldSimilarityWrapper使用不同的相似性的實現爲每個字段:

public class MySimilarity extends PerFieldSimilarityWrapper { 
    Similarity standardSim = new ClassicSimilarity(); 
    Similarity nolengthSim = new SimilarityWithoutLengthNorm(); 

    @Override 
    public Similarity get(String fieldName) { 
     if (fieldName.equals("someField")) { 
      return nolengthSim; 
     } 
     else { 
      return standardSim; 
     } 
    } 

    //These two methods must be implemented here, as their 
    //calculation is not field specific 
    @Override 
    public float queryNorm (float valueForNormalization) { 
     return standardSim.queryNorm(valueForNormalization); 
    } 

    @Override 
    public float coord (int overlap, int maxOverlap) { 
     return standardSim.coord(overlap, maxOverlap); 
    } 
} 

SimilarityWithoutLengthNorm看起來像:

public class SimilarityWithoutLengthNorm extends ClassicSimilarity{ 
    @Override 
    public float lengthNorm(FieldInvertState state) { 
     return 1; 
    } 
} 
+0

非常感謝你對你的迴應。似乎DefaultSimilarity在5.0中已被棄用。 BM52類似於6.0中的默認值。是否有相當於BM52Similarity中的重寫lengthNorm(...)?它似乎沒有實現這個功能。 – loopforever

+0

@loopforever - 實際上,它最近在5.5版本中被棄用了。如果你想切換到BM25,你需要實現EncodeNorm和DecodeNorm方法。請記住,這是一個完全不同的相關性評分算法。 – femtoRgon

+0

看來,在我的測試案例中,除了一個字段(兩個字段之間的長度不同)之外,兩個文檔在計分方面都相同,但仍然產生不同的fieldNorm值:https:// gist。 github.com/anonymous/7e9c5194e671a0c7886a。也許我做錯了什麼?我只是在搜索時添加了searcher.setSimilarity(新的CustomSimilarity())。我應該在索引時間做些什麼?再次感謝你的幫助。 – loopforever