欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

ES解決深分頁問題以及實現(xiàn)Scroll查詢API的示例分析

這篇文章給大家介紹ES解決深分頁問題以及實現(xiàn)Scroll 查詢 API的示例分析,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

專業(yè)從事企業(yè)網(wǎng)站建設和網(wǎng)站設計服務,包括網(wǎng)站建設、國際域名空間、網(wǎng)站空間、企業(yè)郵箱、微信公眾號開發(fā)、微信支付寶小程序設計成都app軟件開發(fā)、軟件開發(fā)、等服務。公司始終通過不懈的努力和以更高的目標來要求自己,在不斷完善自身管理模式和提高技術研發(fā)能力的同時,大力倡導推行新經(jīng)濟品牌戰(zhàn)略,促進互聯(lián)網(wǎng)事業(yè)的發(fā)展。

一、前言:

ES 普通的分頁查詢有深分頁限制,默認是10000條。(因為越往后面分越耗內存)所以要查詢1萬條以后的數(shù)據(jù),要不就縮小查詢范圍,要不用別的方法。

ES 提供了 scroll 查詢。第一次查詢獲取到scroll_id,下次查詢通過scroll_id直接查詢。scroll相當于維護了一份當前索引段的快照信息,這個快照信息是你執(zhí)行這個scroll查詢時的快照。在這個查詢后的任何新索引進來的數(shù)據(jù),都不會在這個快照中查詢到。但是它相對于from和size,不是查詢所有數(shù)據(jù)然后剔除不要的部分,而是記錄一個讀取的位置,保證下一次快速繼續(xù)讀取。而且也不能排序,只能按默認的文檔順序,比較適合查詢掃描全量數(shù)據(jù)。

1、看一個DEMO
private static void scrollSearch(String indexName, String typeName,
            String... ids) {
        IdsQueryBuilder qb = QueryBuilders.idsQuery().addIds(ids);
        SearchResponse sResponse = client.prepareSearch(indexName)
                .setTypes(typeName)
                .setQuery(qb)
                .setScroll(new TimeValue(5000))
                .setSize(50)
                .execute()
                .actionGet();
        int tShards = sResponse.getTotalShards();
        long timeCost = sResponse.getTookInMillis();
        int sShards = sResponse.getSuccessfulShards();
        System.out.println(tShards+","+timeCost+","+sShards);
          
        while (true) {
            SearchHits hits = sResponse.getHits();
            SearchHit[] hitArray = hits.getHits();
            for(int i = 0; i < hitArray.length; i++) {
                SearchHit hit = hitArray[i];
                Map<String, Object> fields = hit.getSource();
                for(String key : fields.keySet()) {
                    System.out.println(key);
                    System.out.println(fields.get(key));
                }
            }
            sResponse = client.prepareSearchScroll(sResponse.getScrollId()).setScroll(new TimeValue(5000)).execute().actionGet();
            //Break condition: No hits are returned
            if (sResponse.getHits().getHits().length == 0) {
                break;
            }
        }
    }
2、自己實現(xiàn)的基礎API
// 接口定義
 
 
/**
 * Scroll 游標全量數(shù)據(jù)查詢 (不支持排序,只按照doc_id排序)
 *
 * @param clazz 實體類類型
 * @param query 查詢參數(shù)
 * @param scrollId 游標
 * @param size 一次拿取數(shù)據(jù)多少。
 * @param <T>
 * @return
 */
<T extends EEntity> EsScrollResponse<T> listByQueryScroll(Class<T> clazz, IQuery query, String scrollId,int size);
 
 
// 具體實現(xiàn)
@Override
public <T extends EEntity> EsScrollResponse<T> listByQueryScroll(Class<T> clazz, IQuery query, String scrollId, int size) {
    // 參數(shù)校驗
    if (size < 1 || size > 200) {
        throw new RuntimeException("ES 查詢一次請求的數(shù)了超出范圍,請在 1-200 之間");
    }
    // 返回結果初始化
    EsScrollResponse response = new EsScrollResponse<>();
    List<T> result = new ArrayList<>();
    // 獲取文檔信息
    Document document = clazz.getAnnotation(Document.class);
    // 全局使用的查詢返回參數(shù)初始化。
    SearchResponse searchResponse = null;
    // 第一次查詢沒有游標,獲取數(shù)據(jù)并記錄游標
    if (StringUtils.isEmpty(scrollId)) {
        SearchRequestBuilder searchRequestBuilder = esDataSource.getClient().prepareSearch(document.indexName()).setTypes(document.type()).setQuery(query.buildQuery()).setScroll(TimeValue.timeValueMinutes(ES_TIME_OUT_MINUTES)).setSize(size);
        searchResponse = searchRequestBuilder.setTimeout(TimeValue.timeValueMinutes(ES_TIME_OUT_MINUTES)).execute().actionGet();
    } else {
        // 有游標按游標進行查詢
        SearchScrollRequestBuilder searchScrollRequestBuilder = esDataSource.getClient().prepareSearchScroll(scrollId).setScroll(TimeValue.timeValueMinutes(ES_TIME_OUT_MINUTES));
        searchResponse = searchScrollRequestBuilder.execute().actionGet();
    }
    // 處理返回結果
    for (SearchHit hit : searchResponse.getHits()) {
        T rt = JSON.parseObject(hit.getSourceAsString(), clazz);
        result.add(rt);
    }
    response.setData(result);
    response.setScrollId(searchResponse.getScrollId());
    return response;
}
 
 
/**
 * ES Scroll 查詢的封裝實體
 */
@Data
public class EsScrollResponse<T> {
 
    /**
     * 存放數(shù)據(jù)
     */
    private List<T> data;
 
    /**
     * 指定游標
     */
    private String scrollId;
}

三、兩種分頁方式比較

分頁方式

說明

優(yōu)點

缺點

場景

from + size

常用的分頁方式,指定分頁大小和偏移量可以直接獲取到需要的數(shù)據(jù)。但內存消耗特別大,且速度很一般,當我們指定from = 100000,size = 10 的時候,每個node都會取出top 100000的數(shù)據(jù),再進行匯總排序,假設3個node,那么就需要取出3*100000條數(shù)據(jù)進行排序后,再取top10的數(shù)據(jù)進行返回。所以ES默認的from+size的限制設置為10000。在數(shù)據(jù)量到達十萬級百萬級的時候這種分頁方式顯然不合理。

數(shù)據(jù)量小的情況使用最方便,靈活性好,實現(xiàn)簡單內存消耗大,速度一般,數(shù)據(jù)量大的情況面臨深度分頁問題數(shù)據(jù)量較小且能容忍深度分頁問題
scroll(游標)

一種快照的查詢形式,快照一旦形成,本次滾動查詢內便無法查出來新增的那些數(shù)據(jù),而且scroll是無法進行排序的,也無法指定from,那么我們想查看指定頁碼的數(shù)據(jù)就必須將該頁數(shù)據(jù)之前的全部數(shù)據(jù)取出來再進行丟棄,所以scroll一般用于導出全量數(shù)據(jù)。

導出全量數(shù)據(jù)時性能最好無法反應數(shù)據(jù)的實時性(因為是快照版本),維護成本高,需要維護一個 scroll_id,且不支持排序,只按照doc_id排序全量數(shù)據(jù)的導出

關于ES解決深分頁問題以及實現(xiàn)Scroll 查詢 API的示例分析就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

當前題目:ES解決深分頁問題以及實現(xiàn)Scroll查詢API的示例分析
路徑分享:http://chinadenli.net/article28/jigjjp.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作微信公眾號標簽優(yōu)化搜索引擎優(yōu)化全網(wǎng)營銷推廣

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設公司