Search API
在es中進(jìn)行搜索有兩種方式筑煮,第一種是uri中使用查詢參數(shù)芜壁,第二種是Request Body Search冕广,使用第二種方式可以實(shí)現(xiàn)各種高級搜索
1.uri search
“GET 索引名(可以加通配符)/_search”:參數(shù)“q”速客,指定查詢字符串,使用Query String Syntax欲账。參數(shù)“df”屡江,指定查詢的字段。
Query String Syntax有這幾種情況
指定字段/泛查詢(查詢所有的字段赛不,除非指定df):q=user:mike/q=mike
Term查詢/Phrase查詢:q=(a b)即包含a或是b的都會計(jì)入結(jié)果/q=“a b”即必須同時(shí)包含a b且順序一致
布爾操作(必須大寫):上面的q=(a b)可以等價(jià)為q=(a OR b)
+/- :即增加must或must not的條件 如q=(a +b)即理解為should a must b
接下來主要介紹Request Body Search
2.基于詞項(xiàng)查詢和基于全文查詢
a.term查詢屬于是基于詞項(xiàng)的查詢惩嘉,es不會對查詢條件做分詞處理,比如下面的查詢就無法查出fullname有Eddie的數(shù)據(jù)俄删,而將條件改為“eddie”后就可以查到結(jié)果了
原因是因?yàn)槟J(rèn)的分詞器在索引時(shí)會將大寫轉(zhuǎn)換為小寫宏怔,所以term查詢不會將查詢條件進(jìn)行分詞處理奏路,就沒辦法在es中索引到數(shù)據(jù)畴椰。
一般可以使用t對字段的keyword進(jìn)行term查詢來進(jìn)行字段的精確匹配
b.而match,match phrase鸽粉,query string都屬于全文查詢斜脂,會對搜索條件進(jìn)行分詞處理
如這個(gè)查詢條件就可以查詢出上面那條數(shù)據(jù)
而match和match phrase的區(qū)別在于,match phrase會將用于查詢的字符串作為一個(gè)短語触机,即搜索結(jié)果中必須同時(shí)有match phrase條件中出現(xiàn)的所有詞匯且順序也一樣且不能在中間插入多余的字符(可以設(shè)置slop參數(shù)以放寬條件)
3.query context & filter context? bool查詢
區(qū)別在于query context會進(jìn)行相關(guān)性算分而filter context不會帚戳,所以filter context的性能更好且可以使用緩存,
bool查詢即must儡首,should片任,must not,filter四種查詢條件蔬胯,通過bool查詢可以將多種查詢條件組合在一起对供,每個(gè)查詢字句的評分會合并到總的相關(guān)性評分中,但后面兩種就屬于filter context不會影響算分。
bool同一層級的查詢條件權(quán)重一樣产场,而查詢可以進(jìn)行嵌套鹅髓,而嵌套內(nèi)的查詢算分權(quán)重會比外層查詢條件低
4.Dis max query與單字符串多字段搜索
都知道在ES中進(jìn)行搜索是會根據(jù)結(jié)果和搜索條件的匹配程度進(jìn)行相關(guān)性算分并根據(jù)算分進(jìn)行排序的,這樣可以盡量將相關(guān)度更高的結(jié)果排列在前面京景,但在單字符串多字段搜索的時(shí)候默認(rèn)的相關(guān)性算分得出的結(jié)果不一定是我們想要的那樣窿冯。比如現(xiàn)在有兩個(gè)文檔
第一個(gè)文檔:{“title”:“a fool boy”, "content”:“he seems laike very fool”}
第二個(gè)文檔:{“title”:“do not be a fool man”, “content”:“this should be a reality”}
如果使用bool查詢對title和content同時(shí)進(jìn)行"fool man"的should match查詢即
{
? ? “query”:{
? ? ? ? "bool"{
? ? ? ? ? ? "should":[
? ? ? ? ? ? ? ? {"match":{"content":"fool man"}},
? ? ? ? ? ? ? ? {"match":{"titile":"fool man"}}
? ? ? ? ? ? ]
????????}
????}
}
按常理來說很明顯第二個(gè)文檔與我們預(yù)期的搜索結(jié)果更匹配,但實(shí)際結(jié)果可能卻是將第一個(gè)文檔排在最前面确徙,因?yàn)樵谟?jì)算相關(guān)性算分時(shí)醒串,should中的兩個(gè)條件對相關(guān)性算分貢獻(xiàn)的權(quán)重是一致的,而第一個(gè)文檔兩個(gè)字段都出現(xiàn)了fool鄙皇,第二個(gè)文檔只有title字段出現(xiàn)了fool man厦凤。所以經(jīng)過相加后第一個(gè)文檔的相關(guān)性算分更高了。這個(gè)時(shí)候?yàn)榱说玫礁项A(yù)期的結(jié)果育苟,我們可以使用Disjunction max query较鼓,
{
? ? “query”:{
? ? ? ? "dis_max"{
? ? ? ? ? ? "querys":[
????????????????{"match":{"content":"fool man"}},
????????????????{"match":{"titile":"fool man"}}
????????????]
????????}
????}
}
這個(gè)查詢的作用就是將單字符串多字段查詢的時(shí)候不會將每個(gè)字段的相關(guān)性算分進(jìn)行簡單相加,而是取算分最高的子段的分作為結(jié)果违柏,這樣就可以查出更符合我們預(yù)期的結(jié)果博烂。