SpringBoot整合Elasticsearch游標查詢的示例代碼(scroll)
游標查詢(scroll)簡介
scroll 查詢 可以用來對 Elasticsearch 有效地執(zhí)行大批量的文檔查詢,而又不用付出深度分頁那種代價。
游標查詢會取某個時間點的快照數(shù)據(jù)。 查詢初始化之后索引上的任何變化會被它忽略。 它通過保存舊的數(shù)據(jù)文件來實現(xiàn)這個特性,結(jié)果就像保留初始化時的索引 視圖 一樣。
啟用游標查詢可以通過在查詢的時候設置參數(shù) scroll 的值為我們期望的游標查詢的過期時間。 游標查詢的過期時間會在每次做查詢的時候刷新,所以這個時間只需要足夠處理當前批的結(jié)果就可以了,而不是處理查詢結(jié)果的所有文檔的所需時間。 這個過期時間的參數(shù)很重要,因為保持這個游標查詢窗口需要消耗資源,所以我們期望如果不再需要維護這種資源就該早點兒釋放掉。 設置這個超時能夠讓 Elasticsearch 在稍后空閑的時候自動釋放這部分資源。
GET /old_index/_search?scroll=1m
{
"query": { "match_all": {}},
"sort" : ["_doc"],
"size": 1000
}
scroll=1m:保持游標查詢窗口一分鐘。
返回結(jié)果示例:
{
"_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": {
...
}
}
]
}
}
這個查詢的返回結(jié)果包括一個字段 _scroll_id, 它是一個base64編碼的長字符串 。 現(xiàn)在我們能傳遞字段 _scroll_id 到 _search/scroll 查詢接口獲取下一批結(jié)果:
GET /_search/scroll
{
"scroll": "1m",
"scroll_id" : "cXVlcnlUaGVuRmV0Y2g7NTsxMDk5NDpkUmpiR2FjOFNhNnlCM1ZDMWpWYnRROzEwOTk1OmRSamJHYWM4U2E2eUIzVkMxalZidFE7MTA5OTM6ZFJqYkdhYzhTYTZ5QjNWQzFqVmJ0UTsxMTE5MDpBVUtwN2lxc1FLZV8yRGVjWlI2QUVBOzEwOTk2OmRSamJHYWM4U2E2eUIzVkMxalZidFE7MDs="
}
注意:需要再次設置游標查詢過期時間為一分鐘。
這個游標查詢返回下一批結(jié)果。
另外盡管我們指定字段 size 的值為1000,但是我們有可能取到超過這個值數(shù)量的文檔。 當查詢的時候, 字段 size 作用于單個分片,所以每個批次實際返回的文檔數(shù)量最大為 size * number_of_primary_shards。
注意:游標查詢每次返回一個新字段 _scroll_id。每次我們做下一次游標查詢, 我們必須把前一次查詢返回的字段_scroll_id 傳遞進去。 當沒有更多的結(jié)果返回的時候,我們就處理完所有匹配的文檔了。
整合
新增以下三個方法:
/**
* 游標查詢
* @param params 查詢?nèi)雲(yún)?
* @param indexName 索引名稱
* @param type 索引類型
* @param defaultSort 默認排序
* @param keyMappings 字段映射
* @param keyMappingsMap 索引對應字段映射
* @param scrollTimeInMillis 游標開啟的時間
* @return Page
*/
protected Page<Map> commonStartScroll(Map<String, String> params, String indexName, String type, String defaultSort,
Map<Key, FieldDefinition> keyMappings,
Map<String, Map<Key, FieldDefinition>> keyMappingsMap, long scrollTimeInMillis) {
SearchQuery searchQuery = buildSearchQuery(params, indexName, type, defaultSort, keyMappings, keyMappingsMap);
return elasticsearchTemplate.startScroll(scrollTimeInMillis, searchQuery, Map.class);
}
/**
* 游標查詢
* @param scrollId 游標ID
* @param scrollTimeInMillis 游標開啟的時間
* @return Page
*/
protected Page<Map> commonContinueScroll(String scrollId, long scrollTimeInMillis) {
return elasticsearchTemplate.continueScroll(scrollId, scrollTimeInMillis, Map.class);
}
/**
* 根據(jù)游標ID清除游標(提早釋放資源,降低ES的負擔)
* @param scrollId 游標ID
*/
protected void clearScroll(String scrollId) {
elasticsearchTemplate.clearScroll(scrollId);
}
StoreSearchService中增加游標查詢方法以及清除游標方法:
/**
* 游標查詢
* @param params 查詢條件
* @return page
*/
public Page<Map> scroll(Map<String, String> params) {
IndexConfig config = indexEntity.getConfigByDocCode(DOC_CODE);
// 如果請求參數(shù)包含游標ID,則說明執(zhí)行翻頁操作,否則認為開啟新的游標查詢
String scrollId = params.getOrDefault(SCROLL_ID, null);
if (StringUtils.isNotBlank(scrollId)) {
return commonContinueScroll(params.get(scrollId), config.getScrollTimeInMillis());
}
return commonStartScroll(params, config.getIndexName(), config.getType(), DEFAULT_SORT,
keyMappings, keyMappingsMap, config.getScrollTimeInMillis());
}
public void clearScroll(String scrollId) {
super.clearScroll(scrollId);
}
對外暴露接口:
@PostMapping("/scroll")
public ResponseResult scroll(@RequestBody Map<String, String> params) {
return ResponseResult.success(storeSearchService.scroll(params));
}
@GetMapping("/scroll/clear/{scrollId}")
public ResponseResult clearScroll(@PathVariable String scrollId) {
storeSearchService.clearScroll(scrollId);
return ResponseResult.success(null);
}
游標查詢分為開啟和繼續(xù)兩個步驟,接口/scroll中根據(jù)_scrollId判斷為開啟游標查詢還是繼續(xù)游標查詢。
若條件允許的話,盡量將游標查詢及時關(guān)閉,以釋放ES集群的資源,降低負擔。
源碼
Git項目地址:https://github.com/lifengdi/search
原文鏈接:https://www.lifengdi.com/archives/article/2119
到此這篇關(guān)于SpringBoot整合Elasticsearch游標查詢(scroll)的文章就介紹到這了,更多相關(guān)SpringBoot整合Elasticsearch內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Jmeter壓力測試簡單教程(包括服務器狀態(tài)監(jiān)控)
Jmeter是一個非常好用的壓力測試工具。Jmeter用來做輕量級的壓力測試,非常合適,本文詳細的介紹了Jmeter的使用,感性的可以了解一下2021-11-11
Java?Spring?Dubbo三種SPI機制的區(qū)別
這篇文章主要介紹了Java?Spring?Dubbo三種SPI機制的區(qū)別,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下2022-08-08

