/
page.go
87 lines (80 loc) · 2.12 KB
/
page.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package esutils
import (
"context"
"encoding/json"
"github.com/olivere/elastic"
"github.com/pkg/errors"
)
// PageResult represents result of pagination
type PageResult struct {
Page int `json:"page"` // from 1
PageSize int `json:"page_size"`
Total int `json:"total"`
Docs []interface{} `json:"docs"`
HasNextPage bool `json:"has_next_page"`
}
// Page fetch pagination result
func (es *Es) Page(ctx context.Context, paging *Paging) (PageResult, error) {
var (
err error
boolQuery *elastic.BoolQuery
pr PageResult
)
if paging == nil {
paging = &Paging{
Limit: -1,
}
}
if paging.Limit < 0 || paging.Limit > 10000 {
docs, err := es.List(ctx, paging, nil)
if err != nil {
return pr, errors.Wrap(err, "call List() error")
}
pr.Total = len(docs)
pr.Docs = docs
return pr, nil
}
boolQuery = query(paging.StartDate, paging.EndDate, paging.DateField, paging.QueryConds)
var rets []interface{}
var searchResult *elastic.SearchResult
fsc := elastic.NewFetchSourceContext(true)
if len(paging.Includes) > 0 {
fsc = fsc.Include(paging.Includes...)
}
if len(paging.Excludes) > 0 {
fsc = fsc.Exclude(paging.Excludes...)
}
ss := es.client.Search().Index(es.esIndex).Type(es.esType).Query(boolQuery).FetchSourceContext(fsc)
if paging.Sortby != nil && len(paging.Sortby) > 0 {
for _, v := range paging.Sortby {
ss = ss.Sort(v.Field, v.Ascending)
}
}
if searchResult, err = ss.From(paging.Skip).Size(paging.Limit).Do(ctx); err != nil {
return pr, errors.Wrap(err, "call Search() error")
}
for _, hit := range searchResult.Hits.Hits {
var p map[string]interface{}
json.Unmarshal(*hit.Source, &p)
p["_id"] = hit.Id
rets = append(rets, p)
}
pr.Docs = rets
pr.Total = int(searchResult.TotalHits())
pr.PageSize = paging.Limit
if paging.Limit > 0 {
pr.Page = paging.Skip/paging.Limit + 1
}
var totalPage int
if pr.PageSize > 0 {
if pr.Total%pr.PageSize > 0 {
totalPage = pr.Total/pr.PageSize + 1
} else {
totalPage = pr.Total / pr.PageSize
}
}
if pr.Page < totalPage {
pr.HasNextPage = true
}
return pr, err
}