Elasticsearch 實現分頁的 3 種方式,還有誰不會??

来源:https://www.cnblogs.com/javastack/archive/2022/07/01/16435081.html
-Advertisement-
Play Games

一、from + size 淺分頁 "淺"分頁可以理解為簡單意義上的分頁。 它的原理很簡單,就是查詢前20條數據,然後截斷前10條,只返回10-20的數據。這樣其實白白浪費了前10條的查詢。 GET test_dev/_search { "query": { "bool": { "filter": ...


一、from + size 淺分頁

"淺"分頁可以理解為簡單意義上的分頁。

它的原理很簡單,就是查詢前20條數據,然後截斷前10條,只返回10-20的數據。這樣其實白白浪費了前10條的查詢。

GET test_dev/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "age": 28
          }
        }
      ]
    }
  },
  "size": 10,
  "from": 20,
  "sort": [
    {
      "timestamp": {
        "order": "desc"
      },
      "_id": {
        "order": "desc"
      }
    }
  ]
}

其中,from定義了目標數據的偏移值,size定義當前返回的數目。預設from為0,size為10,即所有的查詢預設僅僅返回前10條數據。

在這裡有必要瞭解一下from/size的原理:

因為es是基於分片的,假設有5個分片,from=100,size=10。則會根據排序規則從5個分片中各取回100條數據數據,然後彙總成500條數據後選擇最後面的10條數據。

做過測試,越往後的分頁,執行的效率越低。總體上會隨著from的增加,消耗時間也會增加。而且數據量越大,就越明顯!

二、scroll 深分頁

from+size查詢在10000-50000條數據(1000到5000頁)以內的時候還是可以的,但是如果數據過多的話,就會出現深分頁問題。

為瞭解決上面的問題,elasticsearch提出了一個scroll滾動的方式。

scroll 類似於sql中的cursor,使用scroll,每次只能獲取一頁的內容,然後會返回一個scroll_id。根據返回的這個scroll_id可以不斷地獲取下一頁的內容,所以scroll並不適用於有跳頁的情景。

GET test_dev/_search?scroll=5m
{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "age": 28
          }
        }
      ]
    }
  },
  "size": 10,
  "from": 0,
  "sort": [
    {
      "timestamp": {
        "order": "desc"
      },
      "_id": {
        "order": "desc"
      }
    }
  ]
}
  • scroll=5m表示設置scroll_id保留5分鐘可用。
  • 使用scroll必須要將from設置為0。
  • size決定後面每次調用_search搜索返回的數量

然後我們可以通過數據返回的_scroll_id讀取下一頁內容,每次請求將會讀取下10條數據,直到數據讀取完畢或者scroll_id保留時間截止:

GET _search/scroll
{
  "scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAJZ9Fnk1d......",
  "scroll": "5m"
}

註意:請求的介面不再使用索引名了,而是 _search/scroll,其中GET和POST方法都可以使用。

scroll刪除

根據官方文檔的說法,scroll的搜索上下文會在scroll的保留時間截止後自動清除,但是我們知道scroll是非常消耗資源的,所以一個建議就是當不需要了scroll數據的時候,儘可能快的把scroll_id顯式刪除掉。

清除指定的scroll_id

DELETE _search/scroll/DnF1ZXJ5VGhlbkZldGNo.....

清除所有的scroll:

DELETE _search/scroll/_all

三、search_after 深分頁

scroll 的方式,官方的建議不用於實時的請求(一般用於數據導出),因為每一個 scroll_id 不僅會占用大量的資源,而且會生成歷史快照,對於數據的變更不會反映到快照上。

search_after 分頁的方式是根據上一頁的最後一條數據來確定下一頁的位置,同時在分頁請求的過程中,如果有索引數據的增刪改查,這些變更也會實時的反映到游標上。但是需要註意,因為每一頁的數據依賴於上一頁最後一條數據,所以無法跳頁請求。

為了找到每一頁最後一條數據,每個文檔必須有一個全局唯一值,官方推薦使用 _uid 作為全局唯一值,其實使用業務層的 id 也可以。

GET test_dev/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "age": 28
          }
        }
      ]
    }
  },
  "size": 20,
  "from": 0,
  "sort": [
    {
      "timestamp": {
        "order": "desc"
      },
      "_id": {
        "order": "desc"
      }
    }
  ]
}
  • 使用search_after必須要設置from=0
  • 這裡我使用timestamp和_id作為唯一值排序。
  • 我們在返回的最後一條數據里拿到sort屬性的值傳入到search_after

使用sort返回的值搜索下一頁:

GET test_dev/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "age": 28
          }
        }
      ]
    }
  },
  "size": 10,
  "from": 0,
  "search_after": [
    1541495312521,
    "d0xH6GYBBtbwbQSP0j1A"
  ],
  "sort": [
    {
      "timestamp": {
        "order": "desc"
      },
      "_id": {
        "order": "desc"
      }
    }
  ]
}

你都學會了嗎?

版權聲明:本文為CSDN博主「zhexiao27」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。原文鏈接:https://blog.csdn.net/andybegin/article/details/83864171

近期熱文推薦:

1.1,000+ 道 Java面試題及答案整理(2022最新版)

2.勁爆!Java 協程要來了。。。

3.Spring Boot 2.x 教程,太全了!

4.別再寫滿屏的爆爆爆炸類了,試試裝飾器模式,這才是優雅的方式!!

5.《Java開發手冊(嵩山版)》最新發佈,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本篇文章中,將描述如何使用go創建CA,並使用CA簽署證書。在使用openssl創建證書時,遵循的步驟是 創建秘鑰 > 創建CA > 生成要頒發證書的秘鑰 > 使用CA簽發證書。這種步驟,那麼我們現在就來嘗試下。 創建證書的頒發機構 首先,會從將從創建 CA 開始。CA 會被用來簽署其他證書 // ...
  • 本篇代碼提供者: 青燈教育-自游老師 [環境使用]: Python 3.8 Pycharm [模塊使用]: requests >>> pip install requests re json csv 如果安裝python第三方模塊: win + R 輸入 cmd 點擊確定, 輸入安裝命令 pip i ...
  • Java基礎之 數據類型 註釋、標識符、關鍵字 數據類型 類型轉換 變數、常量 運算符 包機制、JavaDoc 數據類型 強類型語言 要求變數的使用要嚴格符合會定,所有變數都必須先定義後才能使用 弱類型語言 變數的使用沒有那麼嚴格 什麼是位元組 位(bit):是電腦 內部數據 儲存的最小單位,110 ...
  • 今天看到一篇博客介紹使用 Lambda 表達式遞歸計算 n!。使用了 C++14 的 generic lambda,給 Lambda 表達式加了一個模板參數,在函數調用的時候將 Lambda 表達式作為參數傳遞給下一層函數。這種方法每次調用函數的時候都要比常規的函數多傳一個參數。我想起兩年前也用 L ...
  • 前言 有時候我們些代碼是總發此疑惑? 為什麼別人採集 xx 網站的時候能成功,而我卻總是不返回給數據 出現這種原因時往往是我們沒有給夠偽裝, 被識別了出來~ 就像人,你出門肯定是要穿衣服的對不,如果你不穿! 走在外面,肯定是最顯眼的一個,不抓你抓誰 還有一種就是明明我之前運行成功了,為什麼我現在再次 ...
  • SpringBoot自動裝配原理 Created time: May 15, 2022 6:36 PM Done: Doing Last edited time: May 25, 2022 6:13 PM Tags: Spring, 後端, 總結 0 關於自動配置 pom.xml spring-bo ...
  • 一、前言 今天帶來的分享是:如何運營好技術相關的自媒體? 這次我會從「理論」和「實踐」兩塊去小小分享: 「理論」分享清楚裡面的商業底層邏輯和框架。對於每個賺錢的案例,底層邏輯和理論都是相通的。分享給大家,自媒體這塊底層邏輯,方便大家在自己的行業裡面,賺更多的錢 「實踐」分享清楚自媒體如何實踐賺錢,如 ...
  • 前言 嗨嘍,大家好呀,這裡是魔王~ 我們空閑時都會聽聽音樂,放鬆一下自己的心情,每個人都會有自己喜歡的歌手或歌 但是通常一個平臺不能完全找到,因為版權原因,經常需要幾個軟體跨著聽,非常的麻煩 那麼現在,我們直接來用代碼全部下載下來用本地播放器播放,美滋滋! 開發環境: 版 本:python3.8 編 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...