02.组合查询
文章目錄
- 1.bool查詢
- 1.1. 使用樣例
- 1.2. filter的使用
- 2. boost query
- 3. constant score query
- 4. disjunction max query
- 5. function score
- 5.1. score_mode boost_mode的含義
- 5.2. function的類型
- 1.script_score
- 2.weight
- 3.random_score
- 4.field_value_factor
- 5.decay functions: gauss, linear, exp
- 6. 衰減函數(shù)支持
1.bool查詢
這個是用來組合查詢使用,可以使用下面4個條件
must
子句(查詢)必須出現(xiàn)在匹配的文檔中,并將有助于得分。
filter
子句(查詢)必須出現(xiàn)在匹配的文檔中。但是,與查詢分?jǐn)?shù)不同的是,忽略該分?jǐn)?shù)。 Filter子句在過濾器上下文中執(zhí)行,這意味著計(jì)分被忽略,并且子句被考慮用于緩存。
should
子句(查詢)應(yīng)出現(xiàn)在匹配的文檔中。
must_not
子句(查詢)不得出現(xiàn)在匹配的文檔中。子句在過filter context 中執(zhí)行,這意味著計(jì)分被忽略,并且子句被視為用于緩存。由于計(jì)分被忽略,因此所有文檔的分?jǐn)?shù)均返回0。
這個地方的minimum_should_match需要注意,他會對should起作用,但是默認(rèn)值受整個bool查詢中的must,filter影響,如果你沒有明確指定minimum_should_match那么:
這個地方像是一個坑,所以一定要注意,在should和mustorfilter一起使用的話,盡量明確設(shè)置minimum_should_match,否則返回的結(jié)果可能并沒有命中should中的任何一個條件。
bool查詢的score計(jì)算方式是 must和should查詢的score的和
1.1. 使用樣例
POST _search {"query": {"bool" : {"must" : {"term" : { "user" : "kimchy" }},"filter": {"term" : { "tag" : "tech" }},"must_not" : {"range" : {"age" : { "gte" : 10, "lte" : 20 }}},"should" : [{ "term" : { "tag" : "wow" } },{ "term" : { "tag" : "elasticsearch" } }],"minimum_should_match" : 1,"boost" : 1.0}} }1.2. filter的使用
GET _search {"query": {"bool": {"filter": {"term": {"status": "active"}}}} }GET _search {"query": {"bool": {"must": {"match_all": {}},"filter": {"term": {"status": "active"}}}} }GET _search {"query": {"constant_score": {"filter": {"term": {"status": "active"}}}} }2. boost query
positive:(必填)要運(yùn)行的查詢。返回的所有文檔都必須與此查詢匹配。
negative:(必填)查詢用于降低匹配文檔的相關(guān)性得分。
如果返回的文檔與肯定查詢和該negative查詢匹配,文檔的最終相關(guān)性得分按照如下所示規(guī)則進(jìn)行計(jì)算:
negative_boost:(必需,浮點(diǎn)數(shù))0到1.0之間的浮點(diǎn)數(shù),用于降低與否定查詢匹配的文檔的相關(guān)性得分。
3. constant score query
這個查詢一般包裹了一個filter context query,然后賦予每個文檔一個固定的相關(guān)性得分
GET /_search {"query": {"constant_score" : {"filter" : {"term" : { "user" : "kimchy"}},"boost" : 1.2}} }4. disjunction max query
可以翻譯為最相似最重要查詢
返回與一個或多個包裝查詢(稱為查詢子句或子句)匹配的文檔。
如果返回的文檔與多個查詢子句匹配,則dis_max查詢?yōu)樵撐臋n計(jì)算的相關(guān)性得分=max(來自任何匹配子句的最高相關(guān)性得分)+tie*其他匹配的子查詢得分。
您可以使用dis_max在用不同提升因子映射的字段中搜索術(shù)語。
樣例
GET /_search {"query": {"dis_max" : {"queries" : [{ "term" : { "title" : "Quick pets" }},{ "term" : { "body" : "Quick pets" }}],"tie_breaker" : 0.7}} }query
(必需的查詢對象數(shù)組)包含一個或多個查詢子句。返回的文檔必須與這些查詢中的一個或多個匹配。如果一個文檔匹配多個查詢,Elasticsearch將使用最高的相關(guān)性得分。
tie_breaker
(可選,float)0到1.0之間的浮點(diǎn)數(shù),用于增加與多個查詢子句匹配的文檔的相關(guān)性得分。默認(rèn)為0.0。
您可以使用tie_breaker值為多個字段中包含相同術(shù)語的文檔分配比僅在多個字段中最好的包含該術(shù)語的文檔更高的相關(guān)性分?jǐn)?shù),而不必將其與多個中兩個不同術(shù)語的更好的情況混淆領(lǐng)域。
如果文檔與多個子句匹配,則dis_max查詢將計(jì)算該文檔的相關(guān)性得分,如下所示:
如果tie_breaker值大于0.0,則所有匹配子句都計(jì)數(shù),但是得分最高的子句計(jì)數(shù)最多。
5. function score
function_score允許您修改查詢檢索的文檔分?jǐn)?shù)。例如,如果分?jǐn)?shù)函數(shù)在計(jì)算上很昂貴,并且在過濾后的文檔集上計(jì)算分?jǐn)?shù)也足夠使用了,則此功能很有用。
要使用function_score,用戶必須定義一個查詢和一個或多個函數(shù),這些函數(shù)為查詢返回的每個文檔計(jì)算一個新分?jǐn)?shù)。
function_score只能與以下一個函數(shù)一起使用:
GET /_search {"query": {"function_score": {"query": { "match_all": {} },"boost": "5", # 針對整個query的boost乘數(shù)"random_score": {}, # 這個random_score就是預(yù)定義的一個function,es有幾個預(yù)定義的function,后面會講到"boost_mode":"multiply"}} }同時,還可以組合多個function 或者是對一些特殊的doc進(jìn)行function score的計(jì)算
GET /_search {"query": {"function_score": {"query": { "match_all": {} },"boost": "5", "functions": [{"filter": { "match": { "test": "bar" } },"random_score": {}, "weight": 23},{"filter": { "match": { "test": "cat" } },"weight": 42}],"max_boost": 42,"score_mode": "max","boost_mode": "multiply","min_score" : 42}} }上面的這些看不懂不要緊,后面會逐一解釋。
首先,通過定義的function對每個文檔評分。參數(shù)score_mode指定如何組合計(jì)算出的分?jǐn)?shù):
5.1. score_mode boost_mode的含義
score_mode 和 boost_mode 含義一致,但是起作用的地方不一致,score_mode針對的是多個function計(jì)算出來的score如何最終計(jì)算出來這些function對應(yīng)的score,
boost_mode 針對的是如何將上一步計(jì)算的function計(jì)算的score和query查詢得到的score合并得到最終的query score
??因?yàn)閟core 可以在不同的范圍上(例如,衰減函數(shù)的分?jǐn)?shù)在0到1之間,而field_value_factor則是任意的),并且由于有時希望函數(shù)對分?jǐn)?shù)有不同的影響,因此每個函數(shù)的分?jǐn)?shù)都可以由用戶定義weight。weight可以在函數(shù)數(shù)組(上面的示例)中為每個函數(shù)定義,并乘以各個函數(shù)計(jì)算出的分?jǐn)?shù)。如果給定weight而沒有任何其他函數(shù)聲明,則weight充當(dāng)僅返回weight的函數(shù)。
如果將score_mode設(shè)置為avg,則各個分?jǐn)?shù)將由加權(quán)平均值合并。例如,如果兩個function返回分?jǐn)?shù)1和2,并且它們各自的weight分別為3和4,則它們的分?jǐn)?shù)將合并為(1 * 3 + 2 * 4)/(3 + 4)而不是(1 * 3 + 2 * 4)/ 2。
通過設(shè)置max_boost參數(shù),可以將新score限制為不超過特定限制。 max_boost的默認(rèn)值為FLT_MAX。
新計(jì)算的分?jǐn)?shù)與query score 合并。參數(shù)boost_mode定義如何合并:
5.2. function的類型
script_score
weight
random_score
field_value_factor
decay functions: gauss, linear, exp
1.script_score
script_score函數(shù)允許您包裝另一個查詢,并可以選擇使用腳本表達(dá)式從文檔中其他數(shù)字字段值派生的計(jì)算來自定義另一個查詢的評分。這是一個簡單的示例:
GET /_search {"query": {"function_score": {"query": {"match": { "message": "elasticsearch" }},"script_score" : {"script" : {"source": "Math.log(2 + doc['likes'].value)"}}}} }在不同的腳本字段值和表達(dá)式之上,_score腳本參數(shù)可用于基于包裝的查詢來檢索分?jǐn)?shù)。
腳本編譯被緩存以加快執(zhí)行速度。如果腳本具有需要考慮的參數(shù),則最好重用相同的腳本并為其提供參數(shù):
GET /_search {"query": {"function_score": {"query": {"match": { "message": "elasticsearch" }},"script_score" : {"script" : {"params": {"a": 5,"b": 1.2},"source": "params.a / Math.pow(params.b, doc['likes'].value)"}}}} }請注意,與custom_score查詢不同,query的分?jǐn)?shù)將與script評分的結(jié)果相乘。如果希望禁止這種情況,請?jiān)O(shè)置“ boost_mode”:“ replace”
2.weight
weight分?jǐn)?shù)使您可以將分?jǐn)?shù)乘以提供的weight。有時可能需要這樣做,因?yàn)樵谔囟ú樵兩显O(shè)置的boost值會被標(biāo)準(zhǔn)化,而對于此得分函數(shù)則不會。數(shù)字值是float類型。
3.random_score
random_score生成的分?jǐn)?shù)從0到1一直均勻分布,但不包括1。默認(rèn)情況下,它使用內(nèi)部Lucene doc id作為隨機(jī)性的來源,這非常有效,但不幸的是不可復(fù)現(xiàn),因?yàn)槲臋n可能會通過合并重新編號。
如果您希望分?jǐn)?shù)是可復(fù)現(xiàn)的,則可以提供seed和field。然后將基于該seed,所考慮文檔的字段的最小值以及根據(jù)索引名稱和分片ID計(jì)算的salt來計(jì)算最終分?jǐn)?shù),以便獲得具有相同值但存儲在不同索引中的文檔不同的分?jǐn)?shù)。請注意,位于相同分片中且具有相同字段值的文檔將獲得相同的分?jǐn)?shù),因此通常希望使用對所有文檔都具有唯一值的字段。最好的默認(rèn)選擇是使用_seq_no字段,其唯一的缺點(diǎn)是,如果更新文檔,則分?jǐn)?shù)會改變,因?yàn)楦虏僮饕矔耞seq_no字段的值。
可以在不設(shè)置字段的情況下設(shè)置種子,但這已被棄用,因?yàn)檫@需要在_id字段上加載字段數(shù)據(jù),這會占用大量內(nèi)存。
GET /_search {"query": {"function_score": {"random_score": {"seed": 10,"field": "_seq_no"}}} }4.field_value_factor
使用field_value_factor函數(shù)可以使用文檔中的字段來影響得分。與使用script_score函數(shù)類似,但是它避免了腳本編寫的開銷。如果用于多值字段,則在計(jì)算中僅使用該字段的第一個值。
例如,假設(shè)您有一個用數(shù)字likes字段索引的文檔,并希望通過該字段影響文檔的分?jǐn)?shù),那么這樣做的示例如下所示:
GET /_search {"query": {"function_score": {"field_value_factor": {"field": "likes","factor": 1.2,"modifier": "sqrt","missing": 1}}} }上面的查詢,對應(yīng)的score會這樣計(jì)算score= sqrt(1.2 * doc[‘likes’].value)
field: 計(jì)算score使用的field
factor: 乘以field.value使用的系數(shù),默認(rèn)是1
modifier: 計(jì)算方式score的方式
missing: 沒有這個field的doc如何打分,這個是默認(rèn)將field.value替換為missing
modifier可以有以下幾種
5.decay functions: gauss, linear, exp
衰減函數(shù)
衰減函數(shù)對文檔進(jìn)行評分,該函數(shù)的衰減取決于文檔的數(shù)字字段值與用戶給定原點(diǎn)的距離。這類似于范圍查詢,但具有平滑的邊緣而不是框。
要對具有數(shù)字字段的查詢使用距離評分,用戶必須為每個字段定義一個原點(diǎn)和一個小數(shù)位數(shù)。需要原點(diǎn)來定義從中計(jì)算距離的“中心點(diǎn)”,并需要標(biāo)度來定義衰減率。衰減函數(shù)指定為
在上面的示例中,該字段是geo_point類型,并且可以以geo格式提供起點(diǎn)。在這種情況下,必須使用單位指定比例和偏移。如果您的字段是日期字段,則可以將比例和偏移量設(shè)置為天,周等。例:
一個完整的樣例
GET /_search {"query": {"function_score": {"gauss": {"date": {"origin": "2013-09-17", "scale": "10d","offset": "5d", "decay" : 0.5 }}}} }參數(shù)解析
origin: 用于計(jì)算距離的原點(diǎn)。對于數(shù)字字段,參數(shù)必須為數(shù)字;對于日期字段,參數(shù)必須為日期;對于地理字段,必須指定為地理點(diǎn)。地理位置和數(shù)字字段必填。對于日期字段,默認(rèn)值為現(xiàn)在。支持日期數(shù)學(xué)(例如now-1h)作為源。
scale: 所有類型均必需。定義到原點(diǎn)的距離+偏移,計(jì)算出的分?jǐn)?shù)將等于衰減參數(shù)。對于地理字段:可以定義為數(shù)字+單位(1km,12m,…)。默認(rèn)單位是米。對于日期字段:可以定義為數(shù)字+單位(“ 1h”,“ 10d”,…。)。默認(rèn)單位是毫秒。對于數(shù)字字段:任何數(shù)字。這個字段主要是配合decay使用,表示距離origin為scale的doc的衰減后的score應(yīng)該為正常的decay定義的數(shù)值
offset:
如果定義了偏移量,則衰減函數(shù)將僅計(jì)算距離大于所定義偏移量的文檔的衰減函數(shù)。默認(rèn)值為0。這個就是說距離origin在offset范圍內(nèi)的值不進(jìn)行衰減
decay
衰減參數(shù)定義了如何結(jié)合scale在距離上對文檔進(jìn)行評分。如果未定義decay,則距離為scale的文檔將獲得0.5分。
在第一個示例中,您的文檔可能代表酒店,并且包含地理位置字段。您要根據(jù)酒店距指定位置的距離來計(jì)算衰減函數(shù)。您可能不會立即看到為高斯功能選擇哪種比例,但是您可以說:“在距所需位置2公里的距離處,分?jǐn)?shù)應(yīng)降低到三分之一。”然后將自動調(diào)整參數(shù)“規(guī)模”,以確保得分函數(shù)為距所需位置2公里的酒店計(jì)算出0.33的得分。
在第二個示例中,字段值在2013-09-12和2013-09-22之間的文檔的權(quán)重為1.0,從origin日期起15天的文檔的權(quán)重為0.5。
6. 衰減函數(shù)支持
這個有很多圖片,參考這里
https://www.elastic.co/guide/en/elasticsearch/reference/7.2/query-dsl-function-score-query.html#_supported_decay_functions
高斯衰減,線性衰減,exp衰減
總結(jié)
- 上一篇: 03.full_text interva
- 下一篇: 04.full_text match查询