/
find.go
137 lines (107 loc) · 3.22 KB
/
find.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package mongodb
import (
"context"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type Find struct {
collection *mongo.Collection
query interface{}
limit int64
skip int64
sort interface{}
projection interface{}
}
func newFind(collection *mongo.Collection, query interface{}) *Find {
return &Find{collection, query, 0, 0, nil, nil}
}
// Find set the find query
func (find *Find) Find(query interface{}) *Find {
find.query = query
return find
}
// Sort set the sort criteria
func (find *Find) Sort(sort interface{}) *Find {
find.sort = sort
return find
}
// Limit set the max number of records to retrieve
func (find *Find) Limit(limit int) *Find {
find.limit = int64(limit)
return find
}
// Skip set the number of records to skip when the query is run
func (find *Find) Skip(skip int) *Find {
find.skip = int64(skip)
return find
}
// Select specifies the fields to return
func (find *Find) Select(projection interface{}) *Find {
find.projection = projection
return find
}
// Count the number of records which match the find query
func (find *Find) Count(ctx context.Context) (int, error) {
count := options.Count()
if find.skip != 0 {
count.SetSkip(find.skip)
}
if find.limit != 0 {
count.SetLimit(find.limit)
}
docCount, err := find.collection.CountDocuments(ctx, find.query, count)
return int(docCount), wrapMongoError(err)
}
// Find a record which matches the find criteria
// Current FindOptions are limited to what is used: Sort, Skip, Projection
// Other exhaustive list of options are: AllowPartialResults,BatchSize,Collation,
// Comment,CursorType,Hint,Max, MaxAwaitTime, MaxTime ,Min,
// NoCursorTimeout,OplogReplay,ReturnKey,ShowRecordID,
// Snapshot,
// ref: https://github.com/mongodb/mongo-go-driver/blob/master/mongo/options/findoptions.go#L306
func (find *Find) One(ctx context.Context, val interface{}) error {
findOneOptions := options.FindOne()
if find.skip != 0 {
findOneOptions.SetSkip(find.skip)
}
if find.sort != nil {
findOneOptions.SetSort(find.sort)
}
if find.projection != nil {
findOneOptions.SetProjection(find.projection)
}
result := find.collection.FindOne(ctx, find.query, findOneOptions)
if result.Err() != nil {
return wrapMongoError(result.Err())
}
result.Decode(val)
return nil
}
// Iter return a cursor to iterate through the results
func (find *Find) Iter() *Cursor {
findOptions := options.Find()
if find.skip != 0 {
findOptions.SetSkip(find.skip)
}
if find.limit != 0 {
findOptions.SetLimit(find.limit)
}
if find.sort != nil {
findOptions.SetSort(find.sort)
}
if find.projection != nil {
findOptions.SetProjection(find.projection)
}
return newCursor(newFindCursor(find.collection, find.query, findOptions))
}
// IterAll return all the results for this query, you do not need to close the cursor after
// this call
func (find *Find) IterAll(ctx context.Context, results interface{}) error {
cursor := find.Iter()
return wrapMongoError(cursor.All(ctx, results))
}
// Distinct return only distinct records
func (find *Find) Distinct(ctx context.Context, fieldName string) ([]interface{}, error) {
results, err := find.collection.Distinct(ctx, fieldName, find.query)
return results, wrapMongoError(err)
}