每個文檔都有相關性評分,用一個相對的浮點數字段
_score
來表示 –
_score
的評分越高,相關性越高。
查詢語句會為每個文檔添加一個
_score
字段。評分的計算方式取決于不同的查詢類型 – 不同的查詢語句用于不同的目的:fuzzy 查詢會計算與關鍵詞的拼寫相似程度,terms查詢會計算 找到的内容與關鍵詞組成部分比對的百分比,但是一般意義上我們說的全文本搜尋是指計算内容與關鍵詞的類似程度。
ElasticSearch的相似度算法被定義為 TF/IDF,即檢索詞頻率/反向文檔頻率,包括一下内容:
-
檢索詞頻率:
檢索詞在該字段出現的頻率?出現頻率越高,相關性也越高。
字段中出現過5次要比隻出現過1次的相關性高。
-
反向文檔頻率:
每個檢索詞在索引中出現的頻率?頻率越高,相關性越低。
檢索詞出現在多數文檔中會比出現在少數文檔中的權重更低, 即檢驗一個檢索詞在文檔中的普遍重要性。
(檢索詞字段在目前文檔出現次數與索引中其他文檔的出現總數的比率)
-
字段長度準則:
字段的長度是多少?長度越長,相關性越低。 檢索詞出現在一個短的
要比同樣的詞出現在一個長的 title
字段。content
了解評分标準
當調試一條複雜的查詢語句時,想要了解相關性評分
_score
是比較困難的。ElasticSearch 在 每個查詢語句中都有一個
explain
參數,将
explain
設為
true
就可以得到更詳細的資訊。
GET /_search?explain <1>
{
"query" : { "match" : { "tweet" : "honeymoon" }}
}
explain
參數可以讓傳回結果添加一個
_score
評分的得來依據。
增加一個
explain
參數會為每個比對到的文檔産生一大堆額外内容,但是花時間去了解它是很有意義的。 如果現在看不明白也沒關系 – 等你需要的時候再來回顧這一節就行。下面我們來一點點的了解這塊知識點。
首先,我們看一下普通查詢傳回的中繼資料:
{ "_index" : "us", "_type" : "tweet", "_id" : "12", "_score" : 0.076713204, "_source" : { ... trimmed ... }, }
這裡加入了該文檔來自于哪個節點哪個分片上的資訊,這對我們是比較有幫助的,因為詞頻率和 文檔頻率是在每個分片中計算出來的,而不是每個索引中:
"_shard" : 1, "_node" : "mzIVYCsqSWCG_M_ZffSs9Q",
然後傳回值中的
_explanation
會包含在每一個入口,告訴你采用了哪種計算方式,并讓你知道計算的結果以及其他詳情:
"_explanation": { "description": "weight(tweet:honeymoon in 0) [PerFieldSimilarity], result of:", "value": 0.076713204, "details": [ { "description": "fieldWeight in 0, product of:", "value": 0.076713204, "details": [ { "description": "tf(freq=1.0), with freq of:", "value": 1, "details": [ { "description": "termFreq=1.0", "value": 1 } ] }, { "description": "idf(docFreq=1, maxDocs=1)", "value": 0.30685282 }, { "description": "fieldNorm(doc=0)", "value": 0.25, } ] } ] }
honeymoon
相關性評分計算的總結 檢索詞頻率 反向文檔頻率 字段長度準則
重要:
輸出
結果代價是十分昂貴的,它隻能用作調試工具
explain
- 千萬不要用于生産環境。 第一部分是關于計算的總結。告訴了我們
在"honeymoon"
字段中的檢索詞頻率/反向文檔頻率或 TF/IDF, (這裡的文檔tweet
是一個内部的ID,跟我們沒有關系,可以忽略。) 然後解釋了計算的權重是如何計算出來的: 檢索詞頻率: 檢索詞0
在honeymoon
字段中的出現次數。 反向文檔頻率: 檢索詞tweet
在honeymoon
字段在目前文檔出現次數與索引中其他文檔的出現總數的比率。 字段長度準則: 文檔中tweet
字段内容的長度 – 内容越長,值越小。 複雜的查詢語句解釋也非常複雜,但是包含的内容與上面例子大緻相同。 通過這段描述我們可以了解搜尋結果是如何産生的。tweet
提示:
JSON形式的explain描述是難以閱讀的
但是轉成 YAML 會好很多,隻需要在參數中加上
format=yaml
Explain Api
文檔是如何被比對到的 當
explain
選項加到某一文檔上時,它會告訴你為何這個文檔會被比對,以及一個文檔為何沒有被比對。 請求路徑為
/index/type/id/_explain
如下所示:
GET /us/tweet/12/_explain { "query" : { "filtered" : { "filter" : { "term" : { "user_id" : 2 }}, "query" : { "match" : { "tweet" : "honeymoon" }} } } }
"failure to match filter: cache(user_id:[2 TO 2])"