1.複合查詢
複合查詢能夠組合其他複合查詢或者查詢子句,同時也可以組合各個查詢的查詢結果及得分,也可以從Query查詢轉換為Filter過濾器查詢。
首先介紹一下Query Context和 Filter Context
1)Query Context查詢主要關注的是文件和查詢條件的匹配度,Query查詢會計算文件和查詢條件的相關度評分。
2)Filter Context過濾器主要關注文件是否匹配查詢條件,並不關係文件和查詢條件的匹配程度,也不會計算文件的相關度評分。過濾器查詢速度比普通查詢快,經常使用的過濾器將被ES自動快取。
GET /kibana_sample_data_ecommerce/_search { "query": { //query context "bool": { "must": [ { "match": { "customer_first_name": "Eddie"}}, { "match": { "customer_gender": "MALE" }} ], "filter": [ // filter context { "term": { "currency": "EUR" }}, { "range": { "order_id": { "gte": "584679" }}} ] } } }
1.1.Boolean Query
Bool查詢由一個或多個bool查詢子句組成,允許組合任意數量的查詢子句,bool查詢共有4鍾查詢型別。
1)must
如果查詢子句為must,那麼must子句中的所有查詢條件都必須在匹配文件中出現。
2)must_not
查詢條件中的任何一部分不能在文件中出現。
3)should
查詢條件可以在匹配文件中出現也可以不出現,但是出現的數量至少要達到minimum_should_match引數所設定的數量,如果組合中使用了must子句,該值預設為0,如果沒有使用該值預設為1.
4)filter
查詢條件必須出現在匹配的文件中,但是該查詢子句對於文件的評分沒有影響,僅對文件進行過濾。
http://127.0.0.1:9200/kibana_sample_data_ecommerce/_search
{ "query": { "bool" : { "must" : [ { "term" : { "day_of_week": "Monday" } }, { "term" : {"customer_gender": "FEMALE"} } ] } } }
1.2Boosting Query
Boosting Query返回和positive查詢條件匹配的文件,減少與negative查詢條件匹配的文件的分數。注意,只有匹配了positive查詢條件的文件才會被返回,negative只是降低同時匹配positive條件和negative查詢條件的文件的相關性評分。negative_boost為介於0和1.0之間的浮點數,用於降低與negative查詢條件匹配的文件相關性評分。
GET /kibana_sample_data_ecommerce/_search { "query": { "boosting" : { "positive" : { "match": { "customer_first_name" : "Eddie" } }, "negative" : { "match" : { "customer_last_name" : "Underwood" } }, "negative_boost" : 0.5 } } }
1.3Constant Score Query
包裝filter查詢,返回所有匹配的文件,但是文件的相關度評分等於查詢傳入的boost值,預設值為1.0。
GET /kibana_sample_data_ecommerce/_search { "query": { "constant_score" : { "filter" : { "match" : { "customer_first_name" : "Eddie"} }, "boost" : 1.2 } } }
1.4Disjunction Max Query
將與任何一個查詢條件匹配的文件作為結果返回,但是採用單個欄位上最匹配的評分作為最終評分返回。
首先看一個不使用dis_max查詢多查詢欄位匹配的例子,
GET /test/_search { "query": { "bool": { "should": [ { "match": { "title": "Brown fox" }}, { "match": { "body": "Brown fox" }} ] } } }
返回:可以看到文件2的body欄位更加匹配查詢條件"body": "Brown fox",但是由於文件1的title欄位和body欄位都有"brown"所以其評分疊加起來比文件2的評分更高。
{ "hits" : { "max_score" : 0.90425634, "hits" : [ { "_index" : "test", "_type" : "_doc", "_id" : "1", "_score" : 0.90425634, "_source" : { "title" : "Quick brown rabbits", "body" : "Brown rabbits are commonly seen." } }, { "_index" : "test", "_type" : "_doc", "_id" : "2", "_score" : 0.77041256, "_source" : { "title" : "Keeping pets healthy", "body" : "My quick brown fox eats rabbits on a regular basis." } } ] } }
dis_max不會將查詢條件各個欄位評分做簡單的相加,而是將與查詢條件匹配得分最高的單個欄位的評分作為文件的評分返回。如下例:
GET /test/_search { "query": { "dis_max": { "queries": [ { "match": { "title": "Brown fox" }}, { "match": { "body": "Brown fox" }} ] } } }
返回:可以看到使用dis_max後文件1的評分降低了。
{
"hits" : { "max_score" : 0.77041256, "hits" : [ { "_index" : "test", "_type" : "_doc", "_id" : "2", "_score" : 0.77041256, "_source" : { "title" : "Keeping pets healthy", "body" : "My quick brown fox eats rabbits on a regular basis." } }, { "_index" : "test", "_type" : "_doc", "_id" : "1", "_score" : 0.6931471, "_source" : { "title" : "Quick brown rabbits", "body" : "Brown rabbits are commonly seen." } } ] } }
dis_max查詢的tie_breaker引數,如果在查詢的時候根據查詢場景需要考慮到其他查詢欄位的得分,則可以使用tie_breaker引數[0.0,1.0],使用tie_beaker之後,計算得分的過程將變為:
1.取到與查詢條件最匹配的單個欄位的評分,2.將與其他查詢條件匹配的得分乘以tie_beaker,3.將1中最高分和2中的得分相加作為文件的評分返回。
1.5Function Score Query
function score query可以在查詢結束後,對每一個匹配的文件重新算分,根據新生成的分數進行排序。
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 } } }
score_mode:每一個文件將會被定義的函式打分,當有多個函式時由score_mode決定如何去組合各個函式的打分,score_mode的幾個方法:multiply,各個得分相乘;sum,分數相加;avg,分數取平均;first,用第一個有match filter的函式的評分;max,選取分數的最大值;min,選取分數的最小值。
weight:因為各個函式的打分範圍不同,例如衰減函式打分範圍為[0,1],而field_value_factor的打分值是任意的,而且有時候希望不同的函式對文件的分數有不同的影響,使用者可以使用weight權重來調整各個函式的得分,在每個function中定義weight的數值,函式計算出文件的得分後將會和其定義的weight值。
max_score:用於限制得分,function算出的新得分會被限制在max_boost內,預設為FLT_MAX。
boost_mode:決定function算出的分和query的得分如何組合:multiply,function和query得分相乘;replace,使用function的得分替換query的得分;sum,兩者得分相加;avg,取兩者均值;max,取兩者較大值;min,取兩者較小值。
min_score:用於排除分值低於閾值的文件。
function score支援的幾種改變分值的函式:
1)script_score:包裝一個子查詢,通過自定義指令碼的方式完全自定義計算文件的得分。
2)Weight:為每個文件設定一個權重,將文件的得分乘以該權重,該引數和boost類似,boost對文件得分的提升不是線性的,文件得分在乘以boost值後會被歸一化(nomalize)處理,所以當不想將得分歸一化處理時即可使用Weight來提升文件的得分。
3)random_score:隨機均勻的產生在[0,1)之間的得分,可以為該函式提供種子(seed)和計算得分的欄位(filed),這樣來保證分數的可複製性。最後的得分將基於seed、filed以及salt(salt由索引名和分片id計算得來),所以有相同的值但是儲存在不同索引中的文件會有不同的評分。但是在同一個分片中並具有相同欄位值的文件將獲得相同的分數,因此通常需要使用具有唯一值的欄位來進行評分。
4)field_value_factor:可以使用文件中的欄位來影響文件的得分
引數:field,用來計算得分的欄位;factor,得分的乘數;modifier,得分的計算公式,可以為none(預設值)
, log
, log1p
, log2p
, ln
, ln1p
, ln2p
, square
, sqrt
, reciprocal;missing,如果指定的filed欄位文件中沒有,預設使用的值。如下計算公式為:
sqrt(1.2 * doc['likes'].value)
"query": {
"function_score": {
"field_value_factor": {
"field": "likes",
"factor": 1.2,
"modifier": "sqrt",
"missing": 1
}
}
}
5)Decay functions:衰減函式,使用者指定一個文件中的欄位的值,衰減函式根據距離這個值的距離來進行打分;查詢時需要為每個欄位定義origin值和scale值,
origin代表的是中心點,用以計算其他值到中心點的距離;
scale代表衰減的範圍,衰減的範圍為[origin-offset-scale,origin-offset],[origin+offset,origin+offset+scale]
此外有兩個可選值:offset、decay
offset表示衰減函式只計算到中心點距離大於offset的文件,即衰減函式計算的範圍是[origin-offset-scale,origin-offset],[origin+offset,origin+offset+scale];
decay表示衰減到兩個邊界上時origin-offset-scale,origin+offset+scale文件的得分,預設為0.5分。如圖:
舉例說明各引數的作用:假設衰減函式的origin定義為100,scale定義為10,offset定義為10,decay為0.5,那麼衰減函式只會計算文件[80,90],[110,120],即介於90與110之間的文件評分與origin得分一樣,在[80,90],[110,120]之間文件得分將會進行衰減,在80,120邊界上的文件得分是
decay:0.5。
如下例所示:DECAY_FUNCTION可以是
linear(線性)、
exp(指數)、
gauss(高斯)這三種衰減函式,FILED_NAME即用來評分的欄位必須為數值型、日期型或地理位置型。
"DECAY_FUNCTION": { "FIELD_NAME": { "origin": "11, 12", "scale": "2km", "offset": "0km", "decay": 0.33 } }
日期型衰減函式:
"function_score": { "gauss": { "date": { "origin": "2013-09-17", "scale": "10d", "offset": "5d", "decay" : 0.5 } } }
如果用於計算衰減的欄位包含多個值,在預設情況下,將選擇最接近原點的值來確定距離,可以通過設定multi_value_mode來改變這個方法:min:衰減距離使用多個欄位距離中的最小值,max:衰減距離使用多個欄位距離中的最大值,avg:衰減距離使用多個欄位距離的平均值,sum衰減距離使用多個欄位距離的和。
2.全文檢索
全文檢索使使用者能夠搜尋分析過的文字,查詢的關鍵字也會被文件索引時使用的分析器進行處理。
2.1Intervals Query
允許對匹配詞項的順序和鄰近性進行細粒度控制。使用者可以應用一個或多個規則集合在指定的欄位上進行操作。
POST _search { "query": { "intervals" : { "my_text" : { "all_of" : { "ordered" : true, "intervals" : [ { "match" : { "query" : "my favorite food", "max_gaps" : 0, "ordered" : true } }, { "any_of" : { "intervals" : [ { "match" : { "query" : "hot water" } }, { "match" : { "query" : "cold porridge" } } ] } } ] } } } } }
interval查詢頂層引數:
Field,使用者希望查詢的欄位,上例為my_text。Field的引數為一個基於詞項匹配度、順序、接近度規則的物件用於匹配文件,上例為{"all_of":"...."}。
有如下一些規則:
1)match:match規則匹配分析後的文字。引數:
query:希望在Field欄位中匹配的內容。
max_gaps:匹配的詞項之間間隔的最大詞數,超過max_gaps的被視為不匹配,預設為-1,如果沒有設定,則對詞項之間的間隔沒有限制;如果設定為0,那麼匹配的詞項之間必須僅僅相鄰。
ordered:如果為true,那麼匹配的詞項出現的順序必須和查詢內容的順序一致,預設為false。
analyzer:用於分析查詢內容的分析器,預設和文件的分析器一致。
filter:intervals filter。
use_field:如果指定該欄位,那麼此規則將應用於該欄位而不是頂層Field欄位。
POST /test/_search { "query": { "intervals" : { "body" : { "match" : { "query" : "quick rabbits", "max_gaps" : 10 } } } } }
2)prefix:字首規則匹配以指定字符集開頭的詞項,prefix最多可以擴充套件到匹配128個字元,如果超過128個字元,ES將返回錯誤。引數:
prefix:希望頂層Field開頭的字元。
analyzer:用以處理prefix的分析器。
use_field:如果指定該欄位,那麼此規則將應用於該欄位而不是頂層Field欄位。
POST /test/_search { "query": { "intervals" : { "body" : { "prefix" : { "prefix" : "Keeping", "use_field":"title" } } } } }
3)wildcard:wildcard使用萬用字元模式,最多能匹配128個詞項。引數:
pattern:萬用字元,支援*、?兩種萬用字元。
analyzer:同上。
use_field:同上。
POST /test/_search { "query": { "intervals" : { "body" : { "wildcard" : { "pattern" : "rab?i*" } } } } }
4)fuzzy:模糊規則匹配與提供的term相似的詞項。引數:
term:需要匹配的詞項。
prefix_length:保持不變的字首的數量。
transpositions:模糊規則是否包含兩個相鄰字元的轉換,預設為true。
fuzziness:通常被解釋為萊文斯坦距離也叫做Edit Distance,指的是一個詞與另一個詞匹配需要編輯的次數,編輯操作替換字元,插入字元,刪除字元,需要編輯的次數越多,說明Edit Distance越大。fuzziness的引數:0,1,2表示最大的編輯次數,預設為AUTO引數,表示根據term的長度自動生成編輯次數。
analyzer:同上。
use_field:同上。
POST /test/_search { "query": { "intervals" : { "body" : { "fuzzy" : { "term" : "rabibst",//需要移動兩次 "fuzziness":2 //兩次edit } } } } }
5)all_of:綜合其他的interval規則,返回的文件必須滿足所有的intervals規則。引數:
intervals:要組合的規則陣列。
max_gaps:
ordered:決定各個規則產生的結果是否排序。
filter:intervals filter。
POST /test/_search { "query": { "intervals" : { "body" : { "all_of" : { "intervals" : [//match、prefix規則均需滿足 { "match" : { "query" : "quick" } }, { "prefix" : { "prefix":"My" } } ] } } } } }
6)any_of:滿足任一子規則的文件即可返回。
intervals:匹配的規則陣列。
filter:intervals filter。
POST /test/_search { "query": { "intervals" : { "body" : { "any_of" : { "intervals" : [ //match、prefix規則滿足其一即可 { "match" : { "query" : "commonly" } }, { "prefix" : { "prefix":"My" } } ] } } } } }
intervals filter引數:
after:匹配的詞項在filter rule後。
before:匹配的詞項在filter rule前。
contained_by:匹配的詞項由filter rule包含。
not_contained_by:匹配的詞項不被filter rule包含。
not_containing:fiter rule不在匹配間隙之間出現。
not_overlapping:匹配的詞項和filter rule不重疊。
overlapping:匹配的詞項和filter rule有重疊。
script:決定文件是否返回的自定義指令碼。
POST /test/_search { "query": { "intervals" : { "body" : { "match" : { "query" : "commonly", "filter":{ "contained_by" : { "match" : { "query" : "Brown seen" //brown seen 必須包含commonly詞項 } } } } } } } }
POST /test/_search { "query": { "intervals" : { "body" : { "match" : { "query" : "brown rabbits", "max_gaps" : 10, "filter":{ "not_containing" : { "match" : { "query" : "fox" //fox 不能出現在brown rabbits 之間 } } } } } } } }
POST /test/_search { "query": { "intervals" : { "body" : { "match" : { "query" : "commonly", "filter":{ "overlapping" : { "match" : { "query" : "Brown seen" //match規則查出的結果文件為Brown rabbits are commonly seen 與commonly 有重疊的地方 } } } } } } } }
2.2Match Query
返回與提供的搜尋文字相匹配的文件,搜尋文字在匹配之前會被分析器進行分析。
引數:
頂層引數:Filed,表示想要搜尋的欄位。
Field下的引數:
1.query:想要在Field欄位中匹配到的內容,match查詢在查詢之前會對查詢內容進行分析。
2.analyzer:分析器,如果field的mapping中有定義分析器,則使用field的分析器,如果沒有,則使用索引預設的分析器。
3.auto_generate_synonyms_phrase_query:是否開啟同義詞匹配,預設為false。
4.fuzziness:模糊匹配,引數見interval query fuzzy。
5.max_expansions:控制模糊匹配fuzzy能擴充套件多少個模糊選項。如test在fuzziness為1的時候,能匹配很多模糊選項:tes,tets,etst等,使用max_expansions控制能匹配多少個模糊選項。
6.prefix_length:fuzzy匹配時,保持不變的字元字首數,預設為0。
7.transpositions:如果true,那麼fuzzy匹配允許字元交換位置,ab->ba。
8.fuzzy_rewrite:重寫查詢的方法,
9.lenient:如果true,則忽略查詢格式錯誤,例如為數值欄位提供文字查詢值。預設為false。
10.operator:用於解析查詢值的bool邏輯。預設為OR,如果Query值為quick brown fox,則匹配規則為quick or brown or fox;此外還有AND值。
11.minimum_should_match:返回的文件必須匹配的子句數量。
12.zero_terms_query:決定當分析器移除所有的分詞時是否返回文件,如當查詢內容中都是停用詞時,所有的分詞被分析器的停用詞過濾器過濾掉時,是否返回文件。預設為none,不返回任何文件,all,返回所有文件。
測試資料: POST /test/_doc/3 { "title": "tets healthy", "body": "My quick brown fox eats rabbits on a regular basis." } POST /test/_doc/4 { "title": "tes healthy", "body": "My quick brown fox eats rabbits on a regular basis." }
測試案例:
POST /test/_search { "query": { "match" : { "title":{ "query":"test", "fuzziness":1, "max_expansions": 1 //最大擴充套件數,test只允許有一個模糊選項,匹配的結果只有一個 } } } }
2.3Match boolean prefix query
match_bool_prefix分析查詢內容,並將分詞出來的各個詞項組合成為一個bool查詢,除了最後一個詞項其他的詞項都會被用在term query中,最後一個詞項被用在prefix query中。
例如:
POST /test/_search { "query": { "match_bool_prefix" : { "message" : "quick brown f" } } }
這個查詢類似於:
POST /test/_search { "query": { "bool" : { "should": [ { "term": { "message": "quick" }}, { "term": { "message": "brown" }}, { "prefix": { "message": "f"}} ] } } }
引數:
頂層引數:Filed,表示想要搜尋的欄位。
1.query:想要在Field欄位中匹配到的內容。
2.analyzer:分析器,預設使用欄位mapping中的分析器。
3.minimum_should_match:返回的文件最少匹配查詢條件的程度。
4.operator:使用AND還是OR去連線詞項。
5.模糊查詢可以用於所有的分詞起器分析出的詞項,除了最後一個詞項。
POST /test/_search { "query": { "match_bool_prefix" : { "body": { "query": "fox eats", "operator":"AND", "fuzziness":1 } } } }
2.4Match phrase query
match_phrase查詢分析搜尋內容並建立一個短語查詢。
match_phrase的詞項之間的間隔為0,analyzer使用查詢欄位mapping欄位定義,如果未定義則使用預設查詢分析器。
GET /test/_search { "query": { "match_phrase" : { "body": { "query": "quick brown fox",
"analyzer":"whitespace" } } } }
2.5Match phrase prefix query
返回包含搜尋內容的文件,與搜尋內容提供的順序一致。搜尋內容的最後一個詞項作為字首匹配任何以字首開始的詞項。
引數:
頂層引數:Filed,表示想要搜尋的欄位。
query:想要搜尋的文字。
analyzer:分析器。
max_expansions:最後一個查詢詞作為字首去匹配到的詞項最多擴充套件數。
slop:分詞之間的最大間隔數,預設為0。
zero_terms_query:見Match Query。
GET /test/_search { "query": { "match_phrase_prefix" : { "body" : { "query" : "quick brown f", "max_expansions": 2 //為2代表以f開頭的詞項只會返回兩種 } } } }
2.6Multi match query
multi match query以match query為基礎,構建多欄位的match查詢。
引數:
1.query:查詢文字。
2.fields:查詢欄位,支援多個欄位,最多查詢欄位數由indices.query.bool.max_clause_count定義,預設為1024個。
3.type:查詢的型別。
best_fields:查詢匹配任意field的文件,但是文件的得分來自最匹配的那個欄位。
most_fields:組合所有欄位的得分,作為文件的評分。
cross_fields:將多個欄位組合成一個欄位,在組合成的欄位裡去查詢。
phrase:每個欄位以match_phrase方式查詢,使用最匹配欄位的得分作為文件的評分。
phrase_prefix:每個欄位以match_phrase_prefix方式查詢,,使用最匹配欄位的得分作為文件的評分。
bool_prefix:每個欄位以match_bool_prefix方式查詢,組合所有欄位的得分作為文件的評分。
4.tie_breaker:當使用tie_breaker時,best_field會根據tie_breaker定義的值的大小,決定除最佳匹配欄位得分以外其他欄位的得分。為tie_breaker * (其他欄位_score)之和。
5.其他引數:analyzer, boost, operator, minimum_should_match, fuzziness, lenient, prefix_length, max_expansions, rewrite, zero_terms_query, cutoff_frequency, auto_generate_synonyms_phrase_query and fuzzy_transpositions。
GET /test/_search { "explain": true, "query": { "multi_match" : { "query": "brown fox", "type": "best_fields", "fields": [ "title", "body" ] } } }
GET /_search { "query": { "multi_match" : { "query": "Will Smith", "type": "cross_fields", "fields": [ "first_name", "last_name" ], "operator": "and" } } }
這個查詢類似與:
(+first_name:will +first_name:smith) | (+last_name:will +last_name:smith)
所有的搜尋詞項都必須在單獨的欄位(也可以是多個欄位組合成的單個欄位,如first_name+last_name)中出現。
2.6Common Terms Query
使用語法基於操作符如:AND OR來解析和分割查詢字串,然後用分析器對分割的部分就行分析,並與文件進行匹配。
引數:
1.query:查詢字串。
2.default_field:當query_string沒有指定查詢欄位時候,預設查詢的欄位。預設值為索引設定的index.query.default_field值,
index.query.default_field預設值為*。
3.allow_leading_wildcard:true的時候,萬用字元*,?可以被作為查詢字串的首個字元。預設為true。
4.analyze_wildcard:true的時候,查詢會分析查詢字串中的萬用字元。
5.analyzer:用於分析查詢字串的分析器,預設為文件索引時候的分析器。
6.auto_generate_synonyms_phrase_query:true的時候,自動建立多同義詞查詢。
7.boost:浮點數用於增加或減少查詢的相關度評分。
8.default_operator:如果沒有定義operator,預設被用作解析查詢字串的操作符。OR(預設)
9.enable_position_increments:
10.fields:希望查詢的欄位的集合。
11.模糊匹配相關:fuzziness,fuzzy_max_expansions模糊匹配最大擴充套件數,fuzzy_prefix_length模糊匹配字首數,fuzzy_transpositions,lenient。
12.max_determinized_states:確定一個查詢需要的最大的自動機的數量。解釋:https://www.jianshu.com/p/9edca9474663?utm_source=desktop&utm_medium=timeline
13.minimum_should_match:返回的文件最少匹配查詢條件的程度。
14.quote_analyzer:用於分析在引號中的查詢文字。
15.phrase_slop:匹配的兩個分詞之間間隔的最大詞項數。
16.quote_field_suffix:附加到引號查詢文字的字尾。
17.rewrite:用於重寫查詢的方法。
18.time_zone:時區,用於轉換日期引數。
2.7Simple Query String
返回匹配查詢字串的文件,使用有限制的但是容錯的語法去解析查詢字串。該查詢使用簡單的語法基於操作符去解析和分割查詢字串,在查詢之前分別分析各個詞項。因為對語法有更多的限制,索引當有不合規的語法時不會返回錯誤,忽略查詢字串中不合法的部分。
引數:
1.Query:搜尋內容。
2.Fields:搜尋的欄位集合。
3.default_operator:如果沒有定義operator,預設被用作解析查詢字串的操作符。OR(預設)
4.analyze_wildcard:true的時候,查詢會分析查詢字串中的萬用字元。
5.analyzer:用於分析查詢字串的分析器,預設為文件索引時候的分析器。
6.auto_generate_synonyms_phrase_query:true的時候,自動建立多同義詞查詢。
7.flags:查詢操作可以使用的操作符列表。合法操作符:AND、ESCAPE、FUZZY、NEAR、NONE、NOT、OR、PHRASE、PRECEDENCE、PREFIX、SLOP、WHITESPACE。
8.其他引數:fuzzy_max_expansions、fuzzy_prefix_length、fuzzy_transpositions、lenient、minimum_should_match、quote_field_suffix。