我們go項目裏使用的es客戶端是olivere/elastic包,資料比較少,SearchAfter的實現更是少,所以記錄下來給有緣人,也給記性差的自己。
關於深度分頁、淺分頁的區別優缺點另行了解,我的es版本是6.4,過低版本會不支持
關於SearchAfter官方的簡單實例
https://www.elastic.co/guide/en/elasticsearch/reference/6.4/search-request-search-after.html
簡單演示下客戶端的創建:
import "github.com/olivere/elastic"
// 獲取客戶端對象,這裏可以包裝單例使用
esClient, err = elastic.NewClient(
elastic.SetURL(你的es庫host,多參數),
elastic.SetSniff(false),
elastic.SetHealthcheckInterval(10 * time.Second),
elastic.SetGzip(true),
)
查詢方法
其中Query方法的參數需要各位組裝自己的查詢條件,參考官方實例
忽略了數據的處理和,重點在深度分頁的用法
// 深度分頁查詢方法,根據上一次查詢的最後一條數據(該條數據的中用於排序的字段值,支持多字段)查詢size條數據
// 入參爲上次調用的返回值,即上次查詢最後一條數據中用於排序的字段值
// 深度分頁不能指定from(只能是0/-1),必須有size和sort
func searchByAfter(searchAfter string) string {
searchService := esClient.Search(要查詢的index/列表).
Query(你的dsl查詢對象).
// 要排序的字段,false爲desc即逆序
Sort("sn", false).
// 每頁的個數
Size(10).
// 爲了兼容第一次請求,判斷searchAfter是否爲空
if searchAfter != "" {
searchService.SearchAfter(searchAfter)
}
// 執行查詢
res, err := searchService.Do(esCtx)
// 省略判斷err和res中數據的處理邏輯,比如轉化成對象列表作爲返回值
list := doSomething(res)
if len(list) <= 0 {
return ""
}
// 本例根據Sn字段排序,所以返回最後一條數據的Sn
return list, list[len(list)-1].Sn
}
查詢方法的使用
是我的單測簡化出來的,肯定不能直接運行,用於演示循環分頁查詢
// 對深度分頁方法的使用測試
func TestEsOrdersDao_OrdersByConditions(t *testing.T) {
var searchAfter string
for {
sn := searchByAfter(searchAfter)
result = append(result, list...)
// 即本次查詢爲空,沒有下一條了
if sn == "" {
break
}
searchAfter = sn
}
// 因爲沒有返回數據,完成後沒什麼好輸出的,可以返回查詢到的數據列表append到數組中彙總
// 斷點調試可以看到每次循環查詢到的數據和每次返回的searchAfter
}