es 分頁兩種方法
Elasticsearch中資料都儲存在分片中,當執行搜尋時每個分片獨立搜尋後,資料再經過整合返回。那麼,如果要實現分頁查詢該怎麼辦呢?
更多內容參考Elasticsearch資料彙總
按照一般的查詢流程來說,如果我想查詢前10條資料:
- 1 客戶端請求發給某個節點
- 2 節點轉發給個個分片,查詢每個分片上的前10條
- 3 結果返回給節點,整合資料,提取前10條
- 4 返回給請求客戶端
那麼當我想要查詢第10條到第20條的資料該怎麼辦呢?這個時候就用到分頁查詢了。
from-size"淺"分頁
"淺"分頁的概念是小博主自己定義的,可以理解為簡單意義上的分頁。它的原理很簡單,就是查詢前20條資料,然後截斷前10條,只返回10-20的資料。這樣其實白白浪費了前10條的查詢。
查詢的方法如:
{
"from" : 0, "size" : 10,
"query" : {
"term" : { "user" : "kimchy" }
}
}
其中,from定義了目標資料的偏移值,size定義當前返回的事件數目。
預設from為0,size為10,即所有的查詢預設僅僅返回前10條資料。
做過測試,越往後的分頁,執行的效率越低。
通過下圖可以看出,刨去一些異常的資料,總體上還是會隨著from的增加,消耗時間也會增加。而且資料量越大,效果越明顯!
也就是說,分頁的偏移值越大,執行分頁查詢時間就會越長!
scroll“深”分頁
相對於from和size的分頁來說,使用scroll可以模擬一個傳統資料的遊標,記錄當前讀取的文件資訊位置。這個分頁的用法,不是為了實時查詢資料,而是為了一次性查詢大量的資料(甚至是全部的資料)。
因為這個scroll相當於維護了一份當前索引段的快照資訊,這個快照資訊是你執行這個scroll查詢時的快照。在這個查詢後的任何新索引進來的資料,都不會在這個快照中查詢到。但是它相對於from和size,不是查詢所有資料然後剔除不要的部分,而是記錄一個讀取的位置,保證下一次快速繼續讀取。
API使用方法如:
curl -XGET 'localhost:9200/twitter/tweet/_search?scroll=1m' -d '
{
"query": {
"match" : {
"title" : "elasticsearch"
}
}
}
'
會自動返回一個_scroll_id,通過這個id可以繼續查詢(實際上這個ID會很長哦!):
curl -XGET 'localhost:9200/_search/scroll?scroll=1m&scroll_id=c2Nhbjs2OzM0NDg1ODpzRlBLc0FXNlNyNm5JWUc1'
注意,我在使用1.4版本的ES時,只支援把引數放在URL路徑裡面,不支援在JSON body中使用。
有個很有意思的事情,細心的會發現,這個ID其實是通過base64編碼的:
cXVlcnlUaGVuRmV0Y2g7MTY7MjI3NTp2dFhLSjhsblFJbWRpd2NEdFBULWtBOzIyNzQ6dnRYS0o4bG5RSW1kaXdjRHRQVC1rQTsyMjgwOnZ0WEtKOGxuUUltZGl3Y0R0UFQta0E7MjI4MTp2dFhLSjhsblFJbWRpd2NEdFBULWtBOzIyODM6dnRYS0o4bG5RSW1kaXdjRHRQVC1rQTsyMjgyOnZ0WEtKOGxuUUltZGl3Y0R0UFQta0E7MjI4Njp2dFhLSjhsblFJbWRpd2NEdFBULWtBOzIyODc6dnRYS0o4bG5RSW1kaXdjRHRQVC1rQTsyMjg5OnZ0WEtKOGxuUUltZGl3Y0R0UFQta0E7MjI4NDp2dFhLSjhsblFJbWRpd2NEdFBULWtBOzIyODU6dnRYS0o4bG5RSW1kaXdjRHRQVC1rQTsyMjg4OnZ0WEtKOGxuUUltZGl3Y0R0UFQta0E7MjI3Njp2dFhLSjhsblFJbWRpd2NEdFBULWtBOzIyNzc6dnRYS0o4bG5RSW1kaXdjRHRQVC1rQTsyMjc4OnZ0WEtKOGxuUUltZGl3Y0R0UFQta0E7MjI3OTp2dFhLSjhsblFJbWRpd2NEdFBULWtBOzA7
如果使用解碼工具可以看到:
queryThenFetch;16;2275:vtXKJ8lnQImdiwcDtPT-kA;2274:vtXKJ8lnQImdiwcDtPT-kA;2280:vtXKJ8lnQImdiwcDtPT-kA;2281:vtXKJ8lnQImdiwcDtPT-kA;2283:vtXKJ8lnQImdiwcDtPT-kA;2282:vtXKJ8lnQImdiwcDtPT-kA;2286:vtXKJ8lnQImdiwcDtPT-kA;2287:vtXKJ8lnQImdiwcDtPT-kA;2289:vtXKJ8lnQImdiwcDtPT-kA;2284:vtXKJ8lnQImdiwcDtPT-kA;2285:vtXKJ8lnQImdiwcDtPT-kA;2288:vtXKJ8lnQImdiwcDtPT-kA;2276:vtXKJ8lnQImdiwcDtPT-kA;2277:vtXKJ8lnQImdiwcDtPT-kA;2278:vtXKJ8lnQImdiwcDtPT-kA;2279:vtXKJ8lnQImdiwcDtPT-kA;0;
雖然搞不清楚裡面是什麼內容,但是看到了一堆規則的鍵值對,總是讓人興奮一下!
測試from&size VS scroll的效能
首先呢,需要在java中引入elasticsearch-jar,比如使用maven:
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>1.4.4</version>
</dependency>
然後初始化一個client物件:
private static TransportClient client;
private static String INDEX = "index_name";
private static String TYPE = "type_name";
public static TransportClient init(){
Settings settings = ImmutableSettings.settingsBuilder()
.put("client.transport.sniff", true)
.put("cluster.name", "cluster_name")
.build();
client = new TransportClient(settings).addTransportAddress(new InetSocketTransportAddress("localhost",9300));
return client;
}
public static void main(String[] args) {
TransportClient client = init();
//這樣就可以使用client執行查詢了
}
然後就是建立兩個查詢過程了 ,下面是from-size分頁的執行程式碼:
System.out.println("from size 模式啟動!");
Date begin = new Date();
long count = client.prepareCount(INDEX).setTypes(TYPE).execute().actionGet().getCount();
SearchRequestBuilder requestBuilder = client.prepareSearch(INDEX).setTypes(TYPE).setQuery(QueryBuilders.matchAllQuery());
for(int i=0,sum=0; sum<count; i++){
SearchResponse response = requestBuilder.setFrom(i).setSize(50000).execute().actionGet();
sum += response.getHits().hits().length;
System.out.println("總量"+count+" 已經查到"+sum);
}
Date end = new Date();
System.out.println("耗時: "+(end.getTime()-begin.getTime()));
下面是scroll分頁的執行程式碼,注意啊!scroll裡面的size是相對於每個分片來說的,所以實際返回的數量是:分片的數量*size
System.out.println("scroll 模式啟動!");
begin = new Date();
SearchResponse scrollResponse = client.prepareSearch(INDEX)
.setSearchType(SearchType.SCAN).setSize(10000).setScroll(TimeValue.timeValueMinutes(1))
.execute().actionGet();
count = scrollResponse.getHits().getTotalHits();//第一次不返回資料
for(int i=0,sum=0; sum<count; i++){
scrollResponse = client.prepareSearchScroll(scrollResponse.getScrollId())
.setScroll(TimeValue.timeValueMinutes(8))
.execute().actionGet();
sum += scrollResponse.getHits().hits().length;
System.out.println("總量"+count+" 已經查到"+sum);
}
end = new Date();
System.out.println("耗時: "+(end.getTime()-begin.getTime()));
我這裡總的資料有33萬多,分別以每頁5000,10000,50000的資料量請求,得到如下的執行時間:
可以看到僅僅30萬,就相差接近一倍的效能,更何況是如今的大資料環境...因此,如果想要對全量資料進行操作,快換掉fromsize,使用scroll吧!
相關推薦
es 分頁兩種方法
Elasticsearch中資料都儲存在分片中,當執行搜尋時每個分片獨立搜尋後,資料再經過整合返回。那麼,如果要實現分頁查詢該怎麼辦呢? 更多內容參考Elasticsearch資料彙總 按照一般的查詢流程來說,如果我想查詢前10條資料: 1 客戶端請求發給某個節點2 節點轉發給個個分片,查詢每個分片
分頁兩種場景
通過頁碼分頁:1-1. 入參: page -- 當前頁 pagesize -- 每頁顯示條數 1-2. 出參: itemcount -- 總條數 pagecount -- 總頁數 list -- 資料列表 通過id分頁:2-1. 入參: id -- 查詢id,0代表第一頁 pagesize -- 每
mongoDB分頁的兩種方法
mongoDB的分頁查詢是通過limit(),skip(),sort()這三個函式組合進行分頁查詢的 下面這個是我的測試資料 db.test.find().sort({"age":1}); 第一種方法 查詢第一頁的資料:db.test.find().sor
淺談兩種方法實現瀏覽器內多個標簽頁之間的通信
tools view -s data- oca microsoft oar art set 調用localstorge、cookies等本地存儲方式。 方法一: localstorge在一個標簽頁裏被添加、修改或刪除時,都會觸發一個storage事件,通過在另一個標簽頁裏監
Pagehelper 不分頁幾種情況的解決方法
第一種情況: mybatis 引入版本不對 <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-sp
頁面可返回到前一頁離開時的瀏覽位置兩種方法
方法一:簡單粗暴返回前一頁 1 <a id="aa">News & Events</a> 2 3 4 <script> 5 $("#aa").click(function(){ 6 history.go(-1) 7 }) 8 <
【 MATLAB 】使用 MATLAB 求由差分方程表示的濾波器的響應的兩種方法
例題: 一個3階低通濾波器由下面差分方程描述: y(n) = 0.0181 x(n) + 0.0543 x(n-1) + 0.0543 x(n-2) + 0.0181 x(n-3) + 1.76 y(n-1) - 1.1829 y(n-2) + 0.2781 y(n-3)
兩種方法讓WordPress只在首頁顯示友情連結
對於每個網站的友情連結都是非常重要的因素,一個優秀的外鏈可以為自己的網站帶來非常穩定的流量,有助於我們網站的飛速發展!但是友情連結的設定也是有技巧的,如果按照預設的設定友情連結的話,wp的友情連結是全站顯示而對方的部落格友情連結只顯示在主頁,如此相當於你給對方做了一個全
PAT (Basic Level) Practice (中文) 1037 在霍格沃茨找零錢 (20 分)(C++)(兩種方法)
1037 在霍格沃茨找零錢 (20 分) 如果你是哈利·波特迷,你會知道魔法世界有它自己的貨幣系統 —— 就如海格告訴哈利的:“十七個銀西可(Sickle)兌一個加隆(Galleon),二十九個納特(Knut)兌一個西可,很容易。”現在,給定哈利應付的價錢 P 和他實付的錢 A,你的
Python獲取當前檔名分兩種方法:__file__、sys.argv[0]
Python獲取當前檔名可以通過__file__或者sys.argv[0],下面以test.py檔案為例. test.py: # -*- coding: utf-8 -*- # test.py import sys import os # 絕對路徑 print(__fi
PAT (Advanced Level) Practice 1027 Colors in Mars (20 分)(C++)(甲級)(兩種方法)
1027 Colors in Mars (20 分) People in Mars represent the colors in their computers in a similar way as the Earth people. That is, a color is re
CCF201712-1 最小差值(100分)python兩種方法實現
最小差值 問題描述 問題描述 給定n個數,請找出其中相差(差的絕對值)最小的兩個數,輸出它們的差值的絕對值。 輸入格式 輸入第一行包含一個整數n。 第二行包含n個正整數,相鄰整數之間使用一個空格分隔。 輸出格式 輸出一個整數,表示答案。 樣例輸入
js呼叫列印當前頁的兩種方法
方法一:<%@ page language="java" import="java.util.*" pageEncoding="GBK"%> <%@ page contentType="text/html; charset=GBK"%> <%@
linux下終端分屏使用的兩種方法(screen和tmux)
本文主要介紹兩種終端分屏工具:screen和tmux,分享出來供大家參考學習,下面來看看詳細的介紹: 一、使用screen分屏(只能上下分屏,不能左右分屏) (1)安裝工具 在ubuntu系統中使用sudo apt-get install screen 安裝s
【Jquery】jQuery獲取URL參數的兩種方法
ont ras mil scrip line 兩種方法 lower quest request jQuery獲取URL參數的關鍵是獲取到URL,然後對URL進行過濾處理,取出參數。 location.href是取得URL。location.search是取得URL“?
線程的啟動的兩種方法,Runnable接口,run()的調用
ride 之前 線程終止 源碼解析 star 有意 tro thread類 override 實現並啟動線程有兩種方法1、寫一個類繼承自Thread類,重寫run方法。用start方法啟動線程2、寫一個類實現Runnable接口,實現run方法。用new Thread(Ru
spring 讀取properties的兩種方法
jdbc factor frame ram con framework html tex 讀取 一:直接使用context命名空間 如: <beans xmlns="http://www.springframework.org/schema/beans" xm
Parallels Desktop 12卸載的兩種方法!
對於mac系統虛擬機:Parallels Desktop 12怎麽卸載呢? 首先在Mac電腦中打開應用程序,然後找到Parallels Desktop 12軟件圖標,將它移除至廢紙簍中就可以了。如果我們已經在虛擬機中安裝了Windows,就需要先將這些Windows刪除,這樣才不會占用內存。
js數組去重的兩種方法
遍歷 方法 doc 思路 i++ 代碼 數組去重 -- length 數組去重這種問題經常會遇到,解決方法也有很多,這裏就總結兩種比較常用的方法。 方法一 第一種方法的思路:遍歷數組裏的元素,由第一個元素開始依次按照順序與其後面的元素相比較,如果不同則不
使用Python生成源文件的兩種方法
mob zhang mod pri tid 串接 數字 能夠 package 利用Python的字符串處理模塊,開發者能夠編寫腳本用來生成那些格式同樣的C、C++、JAVA源程序、頭文件和測試文件,從而避免大量的反復工作。本文概述兩種利用Python string類生成