forked from gobeam/mongo-go-pagination
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpagingQuery.go
77 lines (71 loc) · 1.9 KB
/
pagingQuery.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
package mongopagination
import (
"context"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
// PagingQuery struct for holding mongo
// connection, filter needed to apply
// filter data with page, limit, sort key
// and sort value
type PagingQuery struct {
Collection *mongo.Collection
Filter bson.M
Projection *bson.D
SortField *string
SortValue *int
Limit int
Page int
}
// PaginatedData struct holds data and
// pagination detail
type PaginatedData struct {
Data []bson.Raw `json:"data"`
Pagination PaginationData `json:"pagination"`
}
// Find returns two value pagination data with document queried from mongodb and
// error if any error occurs during document query
func (paging *PagingQuery) Find() (paginatedData *PaginatedData, err error) {
skip := getSkip(paging.Page, paging.Limit)
limit := int64(paging.Limit)
opt := &options.FindOptions{
Skip: &skip,
Limit: &limit,
}
if paging.SortField != nil && paging.SortValue != nil {
opt.Sort = bson.D{{*paging.SortField, *paging.SortValue}}
}
if paging.Projection != nil {
opt.Projection = *paging.Projection
}
cursor, err := paging.Collection.Find(context.Background(), paging.Filter, opt)
if err != nil {
return nil, err
}
defer cursor.Close(context.Background())
var docs []bson.Raw
for cursor.Next(context.Background()) {
var document *bson.Raw
if err := cursor.Decode(&document); err == nil {
docs = append(docs, *document)
}
}
paginator := Paging(paging)
paginationInfo := *paginator.PaginationData()
paginationInfo.RecordsOnPage = len(docs)
result := PaginatedData{
Pagination: paginationInfo,
Data: docs,
}
return &result, nil
}
// getSkip return calculated skip value for query
func getSkip(page, limit int) (skip int64) {
if page > 0 {
skip = int64((page - 1) * limit)
} else {
skip = int64(page)
}
return
}