ES 搜索21 (function_score查詢 關鍵字 functions 和 weight 濾集提升權重分)

過濾集提升權重 

回到 忽略 TF/IDF 裏處理過的問題,我們希望根據每個度假屋的特性數量來評分, 當時我們希望能用緩存的過濾器來影響評分,現在 function_score 查詢正好可以完成這件事情。

到目前爲止,我們展現的都是爲所有文檔應用單個函數的使用方式,現在會用過濾器將結果劃分爲多個子集(每個特性一個過濾器),併爲每個子集使用不同的函數。

functions是一個數組,裡面放著的是將要被使用的加強函數列表,我們在裡面使用了3個filter去過濾數據,並且每個filter都設置了一個加強函數,並且還使用了一個會應用到所有文檔的field_value_factor加強函數

可以爲列表裡的每個加強函數都指定一個filter,這樣做的話,只有在文檔滿足此filter的要求,此filter的加強函數纔會應用到文擋上,也可以不指定filter,這樣的話此加強函數就會應用到全部的文擋上

一個文檔可以一次滿足多條加強函數和多個filter,如果一次滿足多個,那麼就會產生多個加強score

因此ES會先使用score_mode定義的方式來合併這些加強score們,得到一個總加強score,得到總加強score之後,纔會再使用boost_mode定義的方式去和old_score做合併
 

GET 127.0.0.1/mytest/doc/_search
{
    "query": {
        "function_score": {
            "query": {
                "match_all": {}  //match_all查出來的所有文檔的_score都是1
            },
            "functions": [
                //第一個filter(使用weight加強函數),如果language是java,加強score就是2
                {
                    "filter": {
                        "term": {
                            "language": "java"
                        }
                    },
                    "weight": 2
                },
                //第二個filter(使用weight加強函數),如果language是go,加強score就是3
                {
                    "filter": {
                        "term": {
                            "language": "go"
                        }
                    },
                    "weight": 3
                },
                //第三個filter(使用weight加強函數),如果like數大於等於10,加強score就是5
                {
                    "filter": {
                        "range": {
                            "like": {
                                "gte": 10
                            }
                        }
                    },
                    "weight": 5
                },
                //field_value_factor加強函數,會應用到所有文檔上,加強score就是like值
                {
                    "field_value_factor": {
                        "field": "like"
                    }
                }
            ],
            "score_mode": "multiply", //設置functions裡面的加強score們怎麼合併成一個總加強score
            "boost_mode": "multiply" //設置old_score怎麼和總加強score合併
        }
    }
}

過濾 vs. 查詢

首先要注意的是 filter 過濾器代替了 query 查詢, 在本例中,我們無須使用全文搜索,只想找到 city 字段中包含 Barcelona 的所有文檔,邏輯用過濾比用查詢表達更清晰。過濾器返回的所有文檔的評分 _score 的值爲 1 。 function_score 查詢接受 query 或 filter ,如果沒有特別指定,則默認使用 match_all 查詢。

評分模式 score_mode

每個函數返回一個結果,所以需要一種將多個結果縮減到單個值的方式,然後才能將其與原始評分 _score 合併。評分模式 score_mode 參數正好扮演這樣的角色, 它接受以下值:

multiply

函數結果求積(默認)。

sum

函數結果求和。

avg

函數結果的平均值。

max

函數結果的最大值。

min

函數結果的最小值。

first

使用首個函數(可以有過濾器,也可能沒有)的結果作爲最終結果

在本例中,我們將每個過濾器匹配結果的權重 weight 求和,並將其作爲最終評分結果,所以會使用 sum 評分模式。

不與任何過濾器匹配的文檔會保有其原始評分, _score 值的爲 1 。

 

其實weight加強函數也是可以不和filter搭配,自己單獨使用的,只是這樣做沒啥意義,因爲只是會給全部的文檔都增加一個固定值而已

  • 不過就DSL語法上來說,他也像其他加強函數一樣,是可以直接使用而不用加filte

GET 127.0.0.1/mytest/doc/_search
{
    "query": {
        "function_score": {
            "query": {
                "match_all": {}
            }
        },
        functions: [
            {
                "weight": 3
            }
        ]
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章