solr 相關度評分,自定義評分

美式不加糖_發表於2017-12-24

ps:臨時寫的,大體的實現和簡單版, 以後會不斷完善 部落格和 程式碼

github:https://github.com/Eric-ly/solr_engine

solr是基於lucene的全文檢索 搜尋引擎,和一般查資料庫相比,solr的一個特色就是它的相關度評分。 這裡介紹一下它的自定義 相關度評分。

solr 相關度評分,自定義評分

solr的評分是需要考慮很多因素的 有一個公式,比如會考慮 一句話中 關鍵字出現的頻率,一片文章中關鍵字出現的頻率和這篇文章的長度 來綜合計算相關度評分。

在實際的業務中,可能不需要這麼複雜的相關度,是需要簡單粗暴的 按照我指定的規則計算相關度,並按照相關度進行排序。使用預設的話 因為因素過多 (比如分數小數太多) 可能不能讓評分按照我自己的方式計算(最後分數)即最後的分數會有差別。

需求問題,比如:

我只想要 滑雪 加10分 然後我根據標題包含滑雪的排序

1.標題 含滑雪 > 標題 不含 滑雪

2.正文含滑雪 >正文不含滑雪

3.文章的質量分 高大於 低

這個時候如果用預設的 我無法 在滑雪中根據正文包含 或者 質量分進行二層,三層排序, 因為 條件1 (標題中包含 滑雪關鍵字的 )的評分 就不一樣 導致 排序結果 從一開始就是錯誤的

所以我需要一個按照我自己定義的規則計算的相關度評分。

solr 相關度評分,自定義評分

這裡我大概介紹一下 如何自定義自己的相關度評分

solr使用的預設相關度是 DefaultSimilarity 類,

1.這裡我們重寫DefaultSimilarityFactory , 獲取自定義的similarity

public class BootSimilarityFactory extends SimilarityFactory {
    @Override
    public Similarity getSimilarity(){
        return new  BootSimilarity();
    }
}
複製程式碼

2.BootSimilarity 中simScorer方法 只是用很少的 因素

    @Override
    public SimScorer simScorer(SimWeight weight, LeafReaderContext context) throws IOException {
        BoostSimWeight boostSimWeight = (BoostSimWeight)weight;
        return new BoostSimScorer(boostSimWeight);
    }
複製程式碼

BootSimScorer 方法,這裡我們可以看到explain 方法 我只是使用了boostSimWeight.boost 分數,而對比 預設方法我們就會發現

    public class BoostSimScorer extends SimScorer{

略
        @Override
        public Explanation explain(int doc, Explanation freq) {
            return Explanation.match(
                    boostSimWeight.boost,
                    "(boost is:" + boostSimWeight.boost + " )",
                    Collections.singleton(freq));
        }

略
    }
複製程式碼

如下是預設的評分:

DefaultSimilarity 繼承TFIDFSimilarity 類,具體方法由TFIDFSimilarity實現。

TFIDFSimilarity 類:
    public final SimWeight computeWeight(float queryBoost, CollectionStatistics collectionStats, TermStatistics... termStats) {
        Explanation idf = termStats.length == 1 ? this.idfExplain(collectionStats, termStats[0]) : this.idfExplain(collectionStats, termStats);
        return new TFIDFSimilarity.IDFStats(collectionStats.field(), idf, queryBoost);
    }
複製程式碼

其中的內部類simScore的explain方法

private final class TFIDFSimScorer extends SimScorer {
略
 public Explanation explain(int doc, Explanation freq) {
      return TFIDFSimilarity.this.explainScore(doc, freq, this.stats, this.norms);
 }
複製程式碼

這個方法太長 我就給大家截圖展示下。

solr 相關度評分,自定義評分
大家會發現這裡面有很多的計算方法。

加之前的效果圖片:

solr 相關度評分,自定義評分

加完之後的效果圖片

solr 相關度評分,自定義評分

相關文章