-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy patheffdsl.go
199 lines (172 loc) · 6.21 KB
/
effdsl.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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
package effdsl
import (
"encoding/json"
)
type M map[string]any
func (m M) MarshalJSON() ([]byte, error) {
type MBase M
return json.Marshal((MBase)(m))
}
type SearchBody struct {
Source json.Marshaler `json:"_source,omitempty"`
From *uint64 `json:"from,omitempty"`
Size *uint64 `json:"size,omitempty"`
Query Query `json:"query,omitempty"`
Sort []SortClauseType `json:"sort,omitempty"`
SearchAfter SearchAfterType `json:"search_after,omitempty"`
Collapse json.Marshaler `json:"collapse,omitempty"`
PIT json.Marshaler `json:"pit,omitempty"`
Suggest Suggest `json:"suggest,omitempty"`
}
type BodyOption func(*SearchBody) error
// A search request by default executes against the most recent visible data of the target indices, which is called point in time. Elasticsearch pit (point in time) is a lightweight view into the state of the data as it existed when initiated. In some cases, it’s preferred to perform multiple search requests using the same point in time. For example, if refreshes happen between search_after requests, then the results of those requests might not be consistent as changes happening between searches are only visible to the more recent point in time.
// [Point in time]: https://www.elastic.co/guide/en/elasticsearch/reference/current/point-in-time-api.html
func WithPIT(id string, keepAlive string) BodyOption {
pit := PIT(id, keepAlive)
return func(sb *SearchBody) error {
sb.PIT = pit
return nil
}
}
// By default, searches return the top 10 matching hits. To page through a larger set of results, you can use the search API's from and size parameters. The from parameter defines the number of hits to skip, defaulting to 0. The size parameter is the maximum number of hits to return. Together, these two parameters define a page of results.
// [Paginate search results]: https://www.elastic.co/guide/en/elasticsearch/reference/current/paginate-search-results.html#paginate-search-results
func WithPaginate(from uint64, size uint64) BodyOption {
return func(sb *SearchBody) error {
if from != 0 {
sb.From = &from
}
sb.Size = &size
return nil
}
}
type SearchAfterType interface {
SearchAfterInfo() string
json.Marshaler
}
type SearchAfterResult struct {
Ok SearchAfterType
Err error
}
// By default, you cannot use from and size to page through more than 10,000 hits. This limit is a safeguard set by the index.max_result_window index setting. If you need to page through more than 10,000 hits, use the search_after parameter instead.
// You can use the search_after parameter to retrieve the next page of hits using a set of sort values from the previous page.
// [Search after]: https://www.elastic.co/guide/en/elasticsearch/reference/current/paginate-search-results.html#search-after
func WithSearchAfter(sortValues ...any) BodyOption {
SearchAfterResult := SearchAfter(sortValues...)
searchAfter := SearchAfterResult.Ok
err := SearchAfterResult.Err
return func(sb *SearchBody) error {
sb.SearchAfter = searchAfter
return err
}
}
type Query interface {
QueryInfo() string
json.Marshaler
}
type QueryResult struct {
Ok Query
Err error
}
func WithQuery(queryResult QueryResult) BodyOption {
query := queryResult.Ok
err := queryResult.Err
// Type assertion
return func(b *SearchBody) error {
b.Query = query
return err
}
}
type MockedQuery M
func (q MockedQuery) QueryInfo() string {
return "Mock query"
}
func (q MockedQuery) MarshalJSON() ([]byte, error) {
type MBase M
return json.Marshal((MBase)(q))
}
func MockQuery(m M) QueryResult {
return QueryResult{
Ok: MockedQuery(m),
Err: nil,
}
}
type SortClauseType interface {
SortClauseInfo() string
json.Marshaler
}
type SortClauseResult struct {
Ok SortClauseType
Err error
}
// Allows you to add one or more sorts on specific fields. Each sort can be reversed as well. The sort is defined on a per field level, with special field name for _score to sort by score, and _doc to sort by index order.
// [Sort search results]: https://www.elastic.co/guide/en/elasticsearch/reference/current/sort-search-results.html#sort-search-results
func WithSort(sortClauseResults ...SortClauseResult) BodyOption {
sortClauses := make([]SortClauseType, 0)
for _, scr := range sortClauseResults {
if scr.Err != nil {
return func(sb *SearchBody) error {
return scr.Err
}
}
sortClauses = append(sortClauses, scr.Ok)
}
return func(sb *SearchBody) error {
if sb.Sort == nil {
sb.Sort = sortClauses
} else {
sb.Sort = append(sb.Sort, sortClauses...)
}
return nil
}
}
// Deprecated: use WithCollapse
func WithCollpse(field string) BodyOption {
return WithCollapse(field)
}
// You can use the collapse parameter to collapse search results based on field values. The collapsing is done by selecting only the top sorted document per collapse key.
// [Collapse search results]: https://www.elastic.co/guide/en/elasticsearch/reference/current/collapse-search-results.html
func WithCollapse(field string) BodyOption {
searchCollapse := Collapse(field)
return func(sb *SearchBody) error {
sb.Collapse = searchCollapse
return nil
}
}
// You can use the _source parameter to select what fields of the source are returned. This is called source filtering.
// The following search API request sets the _source request body parameter to false. The document source is not included in the response.
// [Source filtering]: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-fields.html#source-filtering
func WithSourceFilter(opts ...SourceFitlerOption) BodyOption {
sourceFilter := SourceFilter(opts...)
return func(sb *SearchBody) error {
sb.Source = sourceFilter
return nil
}
}
func Define(opts ...BodyOption) (body *SearchBody, err error) {
body = new(SearchBody)
for _, opt := range opts {
err = opt(body)
if err != nil {
return nil, err
}
}
return body, nil
}
type Suggest interface {
SuggestInfo() string
json.Marshaler
}
type SuggestResult struct {
Ok Suggest
Err error
}
// WithSuggest - allows you to use suggest
func WithSuggest(suggestResult SuggestResult) BodyOption {
suggest := suggestResult.Ok
err := suggestResult.Err
// Type assertion
return func(b *SearchBody) error {
b.Suggest = suggest
return err
}
}