es深分頁查詢所有數據java(es分組查詢使用分頁)

本文目錄一覽:

java查詢的分頁思路!!

分頁顯示一般有兩種實現方式:業務層分頁、數據庫層分頁(以下會用到兩個參數,提前說明下 page:請求第幾頁,size:每頁顯示多少條)

業務層分頁:從數據庫取出所有數據,然後通過傳過來的page和size對所有數據截取,比如一共查了100條數據,保存在list裏面,要求查詢第2頁,每頁顯示10條,則可以通過list屬性,取100條數據 中的第11條到第20條,可通過遍歷實現。

數據庫層分頁:數據庫都會有分頁函數(mysql 是limit函數,sqlServer是row_number()函數,可自行百度下)該方法是通過傳過來的page和size在查詢數據庫時就開始分頁,以mysql為例,查詢第2頁,每頁顯示10條,則sql語句是 」select * from XX limit 10,10「(第一個10表示從下標為10開始查,第二個10是共讀取10條)

性能肯定是第二種分頁方式好,只要搞懂分頁原理,想實現分頁其實很簡單,只要搞清楚分頁是將多條數據中的某幾條挑出來

ES 深度分頁scroll使用方式

我們知道ES對於from+size的個數是有限制的,二者之和不能超過1w。當所請求的數據總量大於1w時,可用scroll來代替from+size。

首次查詢使用方式如下:

接下來的查詢方式如下:

如果你對scroll取出的數據順序沒有要求的話,則可以對「_doc」進行排序,es對這種排序做了優化。使用方式如下:

如果你想通過slice並行分片查詢的話,可以這樣設置:

兩個請求可以同時運行。但是這樣做會有個缺陷,內存佔用較大,且第一次查詢很慢。因為查詢是O(N)的複雜度且每個slice佔用N個bits,N是shard的總文檔數。之後緩存的數據將加快查詢。

為了避免上述情況,可以選擇一個doc_values做slice,但是必須要確保這個field有以下特性:

在第一次查詢時,記錄上一次查詢的位置,在接下來的查詢中獲取到上次查詢的位置,接着查詢。

比如說將查詢order by time offset 0 limit 100,改寫成order by time where time0 limit 100,記錄最後一個$time_max,接下來的查詢order by time offset 100 limit 100,改寫成order by time where time$time_max limit 100。如此往複,可以看出scroll是一個常量查詢延遲和開銷,並無什麼副作用。

關於scroll 和search after的詳細信息,請看 .

對應到java api中,可用addSort(“_doc”, SortOrder.ASC)代替。

怎麼用spring獲取es數據

1. ES和solr都是作為全文搜索引擎出現的。都是基於Lucene的搜索服務器。

2. ES不是可靠的存儲系統,不是數據庫,它有丟數據的風險。

3. ES不是實時系統,數據寫入成功只是trans log成功(類似於MySQL的bin log),寫入成功後立刻查詢查不到是正常的。因為數據此刻可能還在內存里而不是進入存儲引擎里。同理,刪除一條數據後也不是馬上消失。寫入何時可查詢?ES內部有一個後台線程,定時將內存中的一批數據寫入到存儲引擎,此後數據可見。默認後台線程一秒運行一次。該線程運行的越頻繁,寫入性能越低。運行的頻率越低,寫入的性能越高(不會無限高)。

4. 目前已知的單ES集群可以存儲PB級別的數據,不過這個就非常費勁了。TB級別數據沒壓力。

5. 如果使用ES官方提供的jar包訪問,需要JDK1.7及以上。

6. 使用對應的版本訪問ES server。如果ES server端的版本是1.7,那麼請使用ES 1.7的client。如果ES server是2.1,請使用2.1的client。

7. ES索引存在Linux服務器的文件系統之上(背後是文件系統,不是類似於HDFS的分佈式文件系統)

8. ES Java client是線程安全的,全局構建一個即可滿足讀寫需求,不要每次都創建ES client。每次訪問ES都構建新的es client即會拋出次異常。

9. 非常不建議使用ES的動態識別和創建的機制,因為很多情況下這並非你所需要。推薦的做法是在寫數據之前仔細的創建mapping。

10. 強烈不建議在ES中使用深分頁。可能會導致集群不可用。

11. ES是靜態分片,一旦分片數在創建索引時確定那麼後繼不能修改。

12. ES里提供了type,很多人以為type是物理表,一個type的數據是獨立存儲的;但是在ES內部並不是這樣,type在ES內部僅僅是一個字段。所以在很多數據能分為獨立index的情況下,不要放到一個index里用type去分。只有嵌套類和父子類的情況下使用type才是合理的。

13. ES並不提供原生的中文分詞的能力。有第三方的中文分詞的插件,比如ik等。Ik是個toy分詞器,有嚴肅的分詞需求的話,請在使用ES之前使用獨立的分詞器分好詞後向ES寫入。

14. ES中的index,首先會進行分片,每一個分片數據一般都會有自己的副本數據,ES分配分片的策略會保證同一個分片數據和自己的副本不會分配到同一個節點上。當集群中的某一節點宕機後,ES的master在ping該節點時通過一定的策略會發現該節點不存活;會開啟ES的恢復過程

15. ES沒有update的能力。所有的update都是標記刪除老文檔,然後重新insert一條新文檔。

ES深度分頁與批量操作

一、分頁查詢

1.普通分頁查詢

2.深度分頁

其實就是搜索的深淺度,比如第一頁、第二頁、第二十頁等等,是淺分頁。第一萬頁,第兩萬頁等就是很深了

我們在獲取第9999條到10009條數據的時候,其實每個分片都會拿到10009條數據,然後集合在一起,總共是30027條數據,針對這些數據再做排序處理,最後獲得十條數據。

如此一來,搜索的太深,就會造成性能問題,會耗費內存和佔用cpu。而且es為了性能,也不支持超過一萬條數據以上的分頁查詢。解決深度分頁問題,就是應該避免深度分頁的操作(限制分頁頁數)。比如最多提供100頁的展示等。

3.scroll滾動搜索

滾動搜索可以先查詢出一些數據,然後再緊接着以此往下查詢。在第一次查詢的時候會有一個滾動id,相當於一個錨標記,隨後再次滾動搜索需要上次的標記。每次搜索都是基於一個歷史的數據快照,在查詢期間,如果有數據變更,所有的內容不會變化

4.批量查詢mget

未命中的結果也會返回json顯示是否有值。

POST   /_doc/_mget

{

    “ids”:[

        “1008”,

        “1007”,

        “555”

    ]

}

ElasticSearch第5天 es實現分頁查詢的幾種方式

es實現分頁查詢,在ES中有三種方式可以實現分頁:from+size、scroll、search_after

這種分頁方式雖然查詢變快了,但滾動上下文代價很高,每一個 scroll_id 不僅會佔用大量的資源(特別是排序的請求),而且是生成的歷史快照,對於數據的變更不會反映到快照上,那麼在實時情況下如果處理深度分頁的問題呢?es 給出了 search_after 的方式,這是在 = 5.0 版本才提供的功能。

searchAfter的方式通過維護一個實時游標來避免scroll的缺點,它可以用於實時請求和高並發場景。

search_after的理念是,=在不同分片上(假設有5個分片),先按照指定順序排好,根據我們傳的search_after值 ,然後僅取這個值之後的size個文檔。這 5*size 個文檔拿到Es內存中排序後,返回前size個文檔即可。避免了淺分頁導致的內存爆炸情況,經實際使用性能良好,ES空閑狀態下查詢耗時穩定在50ms以內,平均10~20ms。

ElasticSearch之Search_After的注意事項

1.搜索時,需要指定sort,並且保證值是唯一的(可以通過加入_id或者文檔body中的業務唯一值來保證);

2.再次查詢時,使用上一次最後一個文檔的sort值作為search_after的值來進行查詢;

3.不能使用隨機跳頁,只能是下一頁或者小範圍的跳頁(一次查詢出小範圍內各個頁數,利用緩存等技術,來實現小範圍分頁,比較麻煩,比如從第一頁調到第五頁,則依次查詢出2,3,4頁的數據,利用每一次最後一個文檔的sort值進行下一輪查詢,客戶端或服務端都可以進行,如果跳的比較多,則可能該方法並不適用)

它與滾動API非常相似,但與它不同,search_after參數是無狀態的,它始終針對最新版本的搜索器進行解析。因此,排序順序可能會在步行期間發生變化,具體取決於索引的更新和刪除

from+ size 分頁,如果數據量不大或者from、size不大的情況下,效率還是蠻高的。但是在深度分頁的情況下,這種使用方式效率是非常低的,並發一旦過大,還有可能直接拖垮整個ElasticSearch的集群。

scroll 分頁通常不會用在客戶端,因為每一個 scroll_id 都會佔用大量的資源,一般是後台用於全量讀取數據使用

search_after通過維護一個實時游標來避免scroll的缺點,它可以用於實時請求和高並發場景,一般用於客戶端的分頁查詢

大體而言就是在這三種分頁方式中,from + size不適合數據量很大的場景,scroll不適合實時場景,而search after在es5.x版本之後應運而生,較好的解決了這個問題。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/242008.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-12 12:45
下一篇 2024-12-12 12:45

相關推薦

  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java Bean加載過程

    Java Bean加載過程涉及到類加載器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean加載的過程。 一、類加載器 類加載器是Java虛擬機…

    編程 2025-04-29
  • Python讀取CSV數據畫散點圖

    本文將從以下方面詳細闡述Python讀取CSV文件並畫出散點圖的方法: 一、CSV文件介紹 CSV(Comma-Separated Values)即逗號分隔值,是一種存儲表格數據的…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發佈。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Python中讀入csv文件數據的方法用法介紹

    csv是一種常見的數據格式,通常用於存儲小型數據集。Python作為一種廣泛流行的編程語言,內置了許多操作csv文件的庫。本文將從多個方面詳細介紹Python讀入csv文件的方法。…

    編程 2025-04-29
  • Java判斷字符串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字符串中是否存在多個指定字符: 一、字符串遍歷 字符串是Java編程中非常重要的一種數據類型。要判斷字符串中是否存在多個指定字符…

    編程 2025-04-29
  • 如何用Python統計列表中各數據的方差和標準差

    本文將從多個方面闡述如何使用Python統計列表中各數據的方差和標準差, 並給出詳細的代碼示例。 一、什麼是方差和標準差 方差是衡量數據變異程度的統計指標,它是每個數據值和該數據值…

    編程 2025-04-29

發表回復

登錄後才能評論