SpringBoot整合Elasticsearch遊標查詢(scroll)
阿新 • • 發佈:2020-10-16
## 遊標查詢(scroll)簡介
`scroll` 查詢 可以用來對 Elasticsearch 有效地執行大批量的文件查詢,而又不用付出深度分頁那種代價。
遊標查詢會取某個時間點的快照資料。 查詢初始化之後索引上的任何變化會被它忽略。 它通過儲存舊的資料檔案來實現這個特性,結果就像保留初始化時的索引 檢視 一樣。
啟用遊標查詢可以通過在查詢的時候設定引數 `scroll` 的值為我們期望的遊標查詢的過期時間。 遊標查詢的過期時間會在每次做查詢的時候重新整理,所以這個時間只需要足夠處理當前批的結果就可以了,而不是處理查詢結果的所有文件的所需時間。 這個過期時間的引數很重要,因為保持這個遊標查詢視窗需要消耗資源,所以我們期望如果不再需要維護這種資源就該早點兒釋放掉。 設定這個超時能夠讓 Elasticsearch 在稍後空閒的時候自動釋放這部分資源。
```bash
GET /old_index/_search?scroll=1m
{
"query": { "match_all": {}},
"sort" : ["_doc"],
"size": 1000
}
```
scroll=1m:保持遊標查詢視窗一分鐘。
返回結果示例:
```json
{
"_scroll_id": "cXVlcnlUaGVuRmV0Y2g7NTsxMDk5NDpkUmpiR2FjOFNhNnlCM1ZDMWpWYnRROzEwOTk1OmRSamJHYWM4U2E2eUIzVkMxalZidFE7MTA5OTM6ZFJqYkdhYzhTYTZ5QjNWQzFqVmJ0UTsxMTE5MDpBVUtwN2lxc1FLZV8yRGVjWlI2QUVBOzEwOTk2OmRSamJHYWM4U2E2eUIzVkMxalZidFE7MDs=",
"took": 10,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 2633253,
"max_score": 1.0,
"hits": [
{
"_index": "old_index",
"_type": "old_index_type",
"_id": "1",
"_score": 1.0,
"_source": {
...
}
}
]
}
}
```
這個查詢的返回結果包括一個欄位 `_scroll_id`, 它是一個base64編碼的長字串 。 現在我們能傳遞欄位 `_scroll_id` 到 `_search/scroll` 查詢介面獲取下一批結果:
```bash
GET /_search/scroll
{
"scroll": "1m",
"scroll_id" : "cXVlcnlUaGVuRmV0Y2g7NTsxMDk5NDpkUmpiR2FjOFNhNnlCM1ZDMWpWYnRROzEwOTk1OmRSamJHYWM4U2E2eUIzVkMxalZidFE7MTA5OTM6ZFJqYkdhYzhTYTZ5QjNWQzFqVmJ0UTsxMTE5MDpBVUtwN2lxc1FLZV8yRGVjWlI2QUVBOzEwOTk2OmRSamJHYWM4U2E2eUIzVkMxalZidFE7MDs="
}
```
注意:需要再次設定遊標查詢過期時間為一分鐘。
這個遊標查詢返回下一批結果。
另外儘管我們指定欄位 `size` 的值為`1000`,但是我們有可能取到超過這個值數量的文件。 當查詢的時候, 欄位 `size` 作用於單個分片,所以每個批次實際返回的文件數量最大為 `size * number_of_primary_shards`。
注意:遊標查詢每次返回一個新欄位 `_scroll_id`。每次我們做下一次遊標查詢, 我們必須把前一次查詢返回的欄位`_scroll_id` 傳遞進去。 當沒有更多的結果返回的時候,我們就處理完所有匹配的文件了。
## 整合
新增以下三個方法:
```java
/**
* 遊標查詢
* @param params 查詢入參
* @param indexName 索引名稱
* @param type 索引型別
* @param defaultSort 預設排序
* @param keyMappings 欄位對映
* @param keyMappingsMap 索引對應欄位對映
* @param scrollTimeInMillis 遊標開啟的時間
* @return Page
*/
protected Page