- ES的搜尋,會分兩階段進行
- 第一階段 - QUERY
- 第二階段 - Fetch
- Query - then - Fetch
- 使用者發出搜尋請求到ES節點。節點收到請求後,會以Coordinating 節點的身份,在6個主副分片中隨機選擇3個分片,傳送查詢請求
- 被選中的分片執行查詢,進行排序。然後,每個分片都會返回From + Size 個排序後的文件Id 和排序值給Coordinating節點
- Coordinating Node 會將Query階段,從每個分片獲取的排序後的文件Id列表,重新進行排序。選取From 到 From + Size個文件的Id
- 以
multi get
請求的方式,到相應的分片獲取詳細的文件資料
- 效能問題
- 每個分片上需要查的文件個數 = from + size
- 最終協調節點需要處理:number_of_shard * ( from + size)
- 深度分頁
- 相關性算分
- 每個分片都基於自己的分片上的資料進行相關度計算。這會導致打分偏離的情況,特別是資料量很少時,如果文件總數很好的情況下,如果主分片大於1,主分片越多,相關性算分會越不準。
- 資料量不大的時候,可以將主分片數設定為1
- 當資料量足夠大時候,只要保證文件均勻分散在各個分片上,結果一般就不會出現偏差
- 使用 DFS Query Then Fetch
- 搜尋的URL 中指定引數 "_search?search_type=dfs_query_then_fetch"
- 到每個分片把各分片的詞頻和文件頻率進行蒐集,然後完整的進行一次相關性算分,消耗更加多的CPU和記憶體,執行效能低下,一般不建議使用
- 寫入3條記錄 "Good" / "Good moring" / "good morning everyone"
- 使用1個主分片測試,Good應該排在第一,Good DF數值應該是3
- 和20個主分片測試
- 當多個主分片時,3個文件的算分都一樣。可以通過Explain API進行分析
- 在3個主分片上執行DFS Query Then Fetch ,結果和一個分片上一致
DELETE message
PUT message
{
"settings": {
"number_of_shards": 20
}
}
GET message
POST message/_doc?routing=1
{
"content":"good"
}
POST message/_doc?routing=2
{
"content":"good morning"
}
POST message/_doc?routing=3
{
"content":"good morning everyone"
}
POST message/_search
{
"explain": true,
"query": {
"match_all": {}
}
}
POST message/_search
{
"explain": true,
"query": {
"term": {
"content": {
"value": "good"
}
}
}
}
POST message/_search?search_type=dfs_query_then_fetch
{
"query": {
"term": {
"content": {
"value": "good"
}
}
}
}