Elasticsearch搜索類型(query type)詳解

關於我, 邯鄲人
對這類話題感興趣?歡迎發送郵件至 donlianli@126.com;或者關注個人微信公衆號「猿界汪汪隊」
 
es在查詢時,能夠指定搜索類型爲QUERY_THEN_FETCH,QUERY_AND_FEATCH,DFS_QUERY_THEN_FEATCH和DFS_QUERY_AND_FEATCH。那麼這4種搜索類型有什麼區別?
 
分佈式搜索背景介紹:
ES天生就是爲分佈式而生,但分佈式有分佈式的缺點。好比要搜索某個單詞,可是數據卻分別在5個分片(Shard)上面,這5個分片可能在5臺主機上面。由於全文搜索天生就要排序(按照匹配度進行排名),但數據卻在5個分片上,如何獲得最後正確的排序呢?ES是這樣作的,大概分兩步。
step一、ES客戶端會將這個搜索詞同時向5個分片發起搜索請求,這叫Scatter,
step二、這5個分片基於本Shard獨立完成搜索,而後將符合條件的結果所有返回,這一步叫Gather。
客戶端將返回的結果進行從新排序和排名,最後返回給用戶。也就是說,ES的一次搜索,是一次scatter/gather過程(這個跟mapreduce也很相似).
 
然而這其中有兩個問題。
第1、數量問題。好比,用戶須要搜索"雙黃連",要求返回最符合條件的前10條。但在5個分片中,可能都存儲着雙黃連相關的數據。因此ES會向這5個分片都發出查詢請求,而且要求每一個分片都返回符合條件的10條記錄。當ES獲得返回的結果後,進行總體排序,而後取最符合條件的前10條返給用戶。這種狀況,ES5個shard最多會收到10*5=50條記錄,這樣返回給用戶的結果數量會多於用戶請求的數量。
第2、排名問題。上面搜索,每一個分片計算分值都是基於本身的分片數據進行計算的。計算分值使用的詞頻率和其餘信息都是基於本身的分片進行的,而ES進行總體排名是基於每一個分片計算後的分值進行排序的,這就可能會致使排名不許確的問題。若是咱們想更精確的控制排序,應該先將計算排序和排名相關的信息(詞頻率等)從5個分片收集上來,進行統一計算,而後使用總體的詞頻率去每一個分片進行查詢。
 
這兩個問題,估計ES也沒有什麼較好的解決方法,最終把選擇的權利交給用戶,方法就是在搜索的時候指定query type。
一、query and fetch
向索引的全部分片(shard)都發出查詢請求,各分片返回的時候把元素文檔(document)和計算後的排名信息一塊兒返回。這種搜索方式是最快的。由於相比下面的幾種搜索方式,這種查詢方法只須要去shard查詢一次。可是各個shard返回的結果的數量之和多是用戶要求的size的n倍。
二、query then fetch(默認的搜索方式)
若是你搜索時,沒有指定搜索方式,就是使用的這種搜索方式。這種搜索方式,大概分兩個步驟,第一步,先向全部的shard發出請求,各分片只返回排序和排名相關的信息(注意,不包括文檔document),而後按照各分片返回的分數進行從新排序和排名,取前size個文檔。而後進行第二步,去相關的shard取document。這種方式返回的document與用戶要求的size是相等的。
三、DFS query and fetch
這種方式比第一種方式多了一個初始化散發(initial scatter)步驟,有這一步,聽說能夠更精確控制搜索打分和排名。
四、 DFS   query then fetch
比第2種方式多了一個初始化散發(initial scatter)步驟。
 
DSF是什麼縮寫?初始化散發是一個什麼樣的過程?
從es的官方網站咱們能夠指定,初始化散發其實就是在進行真正的查詢以前,先把各個分片的詞頻率和文檔頻率收集一下,而後進行詞搜索的時候,各分片依據全局的詞頻率和文檔頻率進行搜索和排名。顯然若是使用DFS_QUERY_THEN_FETCH這種查詢方式,效率是最低的,由於一個搜索,可能要請求3次分片。但,使用DFS方法,搜索精度應該是最高的。
至於DFS是什麼縮寫,沒有找到相關資料,這個D多是Distributed,F多是frequency的縮寫,至於S多是Scatter的縮寫,整個單詞多是分佈式詞頻率和文檔頻率散發的縮寫。
總結一下,從性能考慮QUERY_AND_FETCH是最快的,DFS_QUERY_THEN_FETCH是最慢的。從搜索的準確度來講,DFS要比非DFS的準確度更高。
相關文章
相關標籤/搜索