Elasticsearch核心技術與實戰學習筆記 43 | 分頁與遍歷:From, Size, Search After & Scroll API

一 序

  本文屬於極客時間Elasticsearch核心技術與實戰學習筆記系列。

二 分頁

2.1 From / Size

  • 默認情況下,查詢按照相關度算分排序,返回前 10 條記錄
  • 容易理解的分頁方案
    • From : 開始位置
    • Size:期望獲取文檔的總數

這裏理解下:我只需要查詢size條數據,而es則需要執行from+size條數據然後處理後返回。所以有很大的開銷。

2.2 分佈式系統中深度分頁的問題  

 ES 天生就是分佈式,查詢信息,但是數據分別保存在多個分片,多臺機器,ES 天生就需要滿足排序的需要(按照相關性算分)
當一個查詢:From = 990 ,Size =10

  • 會在每個分片上先獲取 1000 個文檔。然後,通過 Coordinating Node 聚合所有結果。最後在通過排序選取前 1000 個文檔
  • 頁數越深,佔用內容越多。爲了避免深度分頁帶來的內存開銷。ES 有個設定,默認限定到 10000 個文檔

2.3 demo

超出範圍,會報錯

3 Search After 避免深度分頁的問題

  • 避免深度分頁的性能問題,可以實時獲取下一頁文檔信息
    • 不支持指定頁數(From)
    • 不能往下翻
  • 第一步搜索需要指定 sort,並且保證值是唯一的(可以通過加入_id 保證唯一性)
  • 然後使用上一次,最後一個文檔的 sort 值進行查詢

3.1 demo

  數據準備:

#Scroll API
DELETE users

POST users/_doc
{"name":"user1","age":10}

POST users/_doc
{"name":"user2","age":11}


POST users/_doc
{"name":"user2","age":12}

POST users/_doc
{"name":"user2","age":13}

執行查詢

針對返回的結果wkD_8HIBYdMHFwfFArwf,放到search_after。這樣:

可以看到通過設置search_after的值,是可以避免深度分頁的。

3.2Search After 是如何解決深度分頁的問題

  • 假設 Size 是 10
  • 當查詢 990 -1000
  • 通過唯一排序值定位,將每次要處理的文檔都控制在 10(避免性能開銷)

看到這裏,如果你熟悉MySQL,那麼 自然也會想到MySQL的分頁也可以採取類似的辦法來避免offset導致的分頁的尾頁慢。

4 Scoll API

  • 創建一個快照,有新的數據寫入以後,無法被查找
  • 每次查詢後,輸入上一次的 Scroll Id

4.1demo

數據準備,重新插入3條數據

我們使用scroll 生成快照,時間是5分鐘

再插入一條記錄:

吧第一次的scroll id拷出來,這樣執行查詢,最終只能查出3條記錄。

{
  "_scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAABjfgWNURvOERhUl9RV2U4U2stczl1RmZFQQ==",
  "took" : 5,
  "timed_out" : false,
  "terminated_early" : true,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [ ]
  }
}

文檔4 是快照產生之後插入的,是無法被查到的。

5 不同的搜索類型和使用場景

Regular

  • 需要實時獲取頂部的部分文檔。例如查詢最新的訂單

Scorll

  • 需要全部文檔,例如導出全部數據

Pagination

  • From 和 Size
  • 如何需要深度分頁,則選用 Search After

***************************

理解很重要。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章