ES分頁

本篇文章將會講解ES兩種分頁查詢方法以及優缺點

注意:以下文章中的命令和java代碼均基於ES5.3.0版本

一、from/size分頁

官網文檔地址:https://www.elastic.co/guide/en/elasticsearch/reference/5.3/search-request-from-size.html

查詢的時候帶上from和size兩個參數即可

  • from參數默認爲0,size參數默認爲10
  • 查詢結果索引 from + size 的值不能超出index.max_result_window,默認該值是10000
  • 如果想做深度分頁,可以考慮使用 Scroll 或者Search After 方式。

1.修改默認窗口大小

PUT請求 `{{es-host}}/索引名字/_settings

{
    "index": {
        "max_result_window": 1000000
    }
}

可以適當增大窗口值大小方便常用分頁查詢

2.JAVA API

transportClient.prepareSearch(索引名)
                .setQuery(mixQuery)
                .setFrom((pageNum - 1) * pageSize)
                .setSize(pageSize)
                .setFetchSource(true);

3.優缺點

優點就是簡單,和mysql的分頁很相似

缺點也很明顯,首先,分頁受限於結果窗口大小,而該值默認值僅僅是10000,就算可以調整該分頁大小,仍然讓人心裏不爽快,再者,隨着分頁from的值越來越大,效率會越來越低。from/size的分頁原理是先查詢出所有結果,然後根據from和size進行結果截取,所以勢必會隨着分頁深度的增加效率越來越低。最後,由於需要將查詢結果都加載到內存,有可能會出現內存爆掉的情況發生。

二、Scroll分頁

從from/size的官網爲文檔上來看,如果需要“深分頁”,最好使用Scroll or Search After API。

官網文檔:https://www.elastic.co/guide/en/elasticsearch/reference/5.3/search-request-scroll.html

scroll效率之所以高,是因爲它內部維護着一個“遊標”,類似於指針的東西,每次查詢完size個數據,遊標就會移動到查詢數據的尾部等待下次查詢。

1.初次請求

請求方式

POST

請求地址

{{es-host}}/website/_search?scroll=1m

請求體

{
    "size": 1,
    "query": {
        "match_all": {}
    }
}

響應結果

{
    "_scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAANLb6Flg4V2VGRndwUW91SnBVWUlxcTJzc2cAAAAAADS2-RZYOFdlRkZ3cFFvdUpwVVlJcXEyc3NnAAAAAAA0tvgWWDhXZUZGd3BRb3VKcFVZSXFxMnNzZwAAAAAANLb8Flg4V2VGRndwUW91SnBVWUlxcTJzc2cAAAAAADS2-xZYOFdlRkZ3cFFvdUpwVVlJcXEyc3Nn",
    "took": 1,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
        "total": 5,
        "max_score": 1.0,
        "hits": [
            {
                "_index": "website",
                "_type": "blog",
                "_id": "AXoGPweiCycsj4NKux3V",
                "_score": 1.0,
                "_source": {
                    "name": "test"
                }
            }
        ]
    }
}

初次請求和正常的請求沒什麼區別,就加上一個參數scroll=1m即可,表示本次scroll遊標一分鐘內有效。

接着,拿到的結果中除了正常返回的數據,還多了一個_scroll_id參數,下次請求就可以直接使用該參數進行分頁查詢了。

2.以後的請求

請求方式

GET

請求地址

{{es-host}}/_search/scroll?scroll=1m&scroll_id=DnF1ZXJ5VGhlbkZldGNoBQAAAAAANL04FmJrRjY5VkpFUm0yMjZvc2s5VF91S0EAAAAAADS9NhZia0Y2OVZKRVJtMjI2b3NrOVRfdUtBAAAAAAA0vTcWYmtGNjlWSkVSbTIyNm9zazlUX3VLQQAAAAAANL05FmJrRjY5VkpFUm0yMjZvc2s5VF91S0EAAAAAADS9OhZia0Y2OVZKRVJtMjI2b3NrOVRfdUtB

請求體

響應結果

{
    "_scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAANL04FmJrRjY5VkpFUm0yMjZvc2s5VF91S0EAAAAAADS9NhZia0Y2OVZKRVJtMjI2b3NrOVRfdUtBAAAAAAA0vTcWYmtGNjlWSkVSbTIyNm9zazlUX3VLQQAAAAAANL05FmJrRjY5VkpFUm0yMjZvc2s5VF91S0EAAAAAADS9OhZia0Y2OVZKRVJtMjI2b3NrOVRfdUtB",
    "took": 1,
    "timed_out": false,
    "terminated_early": true,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
        "total": 5,
        "max_score": 1.0,
        "hits": [
            {
                "_index": "website",
                "_type": "blog",
                "_id": "AXlizj8kCycsj4NKuvL8",
                "_score": 1.0,
                "_source": {
                    "name": "cve-2015-1427"
                }
            }
        ]
    }
}

可以看到,再次請求的時候不需要再指定索引名稱和相關的複雜查詢條件,直接告訴ES上一次查詢的遊標_scroll_id即可。

3.JAVA API

SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch(index.split(","))
                .setQuery(mixQuery)
                .setSize(pageSize)
                .setFetchSource(true)
                .setScroll(TimeValue.timeValueMinutes(1))
                .addSort(fieldSortBuilder);

只需要加上 .setFetchSource(true)即可。

第一次查詢之後要正常處理結果數據,並非像是某些文章中講的只是返回scroll_id

之後的查詢則就簡單多了

scrollId = searchResponse.getScrollId();
        while (searchResponse.getHits().getHits().length > 0) {
//處理結果數據
            SearchScrollRequestBuilder searchScrollRequestBuilder = transportClient.prepareSearchScroll(scrollId).setScroll(TimeValue.timeValueMinutes(1));
            searchResponse = searchScrollRequestBuilder.execute().actionGet();
            scrollId = searchResponse.getScrollId();
        }

三、Search After分頁

文檔地址:https://www.elastic.co/guide/en/elasticsearch/reference/5.3/search-request-search-after.html

沒用過,略。

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