@@ -17,99 +17,259 @@ import (
17
17
// number of documents in an index. Use SearchService with
18
18
// a SearchType of count for counting with queries etc.
19
19
type CountService struct {
20
- client * Client
21
- indices []string
22
- types []string
23
- query Query
24
- pretty bool
25
- }
26
-
27
- // CountResult is the result returned from using the Count API
28
- // (http://www.elasticsearch.org/guide/reference/api/count/)
29
- type CountResult struct {
30
- Count int64 `json:"count"`
31
- Shards shardsInfo `json:"_shards,omitempty"`
20
+ client * Client
21
+ pretty bool
22
+ index []string
23
+ typ []string
24
+ allowNoIndices * bool
25
+ analyzeWildcard * bool
26
+ analyzer string
27
+ defaultOperator string
28
+ df string
29
+ expandWildcards string
30
+ ignoreUnavailable * bool
31
+ lenient * bool
32
+ lowercaseExpandedTerms * bool
33
+ minScore interface {}
34
+ preference string
35
+ q string
36
+ query Query
37
+ routing string
38
+ bodyJson interface {}
39
+ bodyString string
32
40
}
33
41
42
+ // NewCountService creates a new CountService.
34
43
func NewCountService (client * Client ) * CountService {
35
- builder := & CountService {
44
+ return & CountService {
36
45
client : client ,
37
46
}
38
- return builder
39
47
}
40
48
41
- func (s * CountService ) Index (indices ... string ) * CountService {
42
- if s .indices == nil {
43
- s .indices = make ([]string , 0 )
49
+ // Index sets the names of the indices to restrict the results.
50
+ func (s * CountService ) Index (index ... string ) * CountService {
51
+ if s .index == nil {
52
+ s .index = make ([]string , 0 )
44
53
}
45
- s .indices = append (s .indices , indices ... )
54
+ s .index = append (s .index , index ... )
46
55
return s
47
56
}
48
57
49
- func (s * CountService ) Type (types ... string ) * CountService {
50
- if s .types == nil {
51
- s .types = make ([]string , 0 )
58
+ // Type sets the types to use to restrict the results.
59
+ func (s * CountService ) Type (typ ... string ) * CountService {
60
+ if s .typ == nil {
61
+ s .typ = make ([]string , 0 )
52
62
}
53
- s .types = append (s .types , types ... )
63
+ s .typ = append (s .typ , typ ... )
64
+ return s
65
+ }
66
+
67
+ // AllowNoIndices indicates whether to ignore if a wildcard indices
68
+ // expression resolves into no concrete indices. (This includes "_all" string
69
+ // or when no indices have been specified).
70
+ func (s * CountService ) AllowNoIndices (allowNoIndices bool ) * CountService {
71
+ s .allowNoIndices = & allowNoIndices
72
+ return s
73
+ }
74
+
75
+ // AnalyzeWildcard specifies whether wildcard and prefix queries should be
76
+ // analyzed (default: false).
77
+ func (s * CountService ) AnalyzeWildcard (analyzeWildcard bool ) * CountService {
78
+ s .analyzeWildcard = & analyzeWildcard
79
+ return s
80
+ }
81
+
82
+ // Analyzer specifies the analyzer to use for the query string.
83
+ func (s * CountService ) Analyzer (analyzer string ) * CountService {
84
+ s .analyzer = analyzer
85
+ return s
86
+ }
87
+
88
+ // DefaultOperator specifies the default operator for query string query (AND or OR).
89
+ func (s * CountService ) DefaultOperator (defaultOperator string ) * CountService {
90
+ s .defaultOperator = defaultOperator
91
+ return s
92
+ }
93
+
94
+ // Df specifies the field to use as default where no field prefix is given
95
+ // in the query string.
96
+ func (s * CountService ) Df (df string ) * CountService {
97
+ s .df = df
98
+ return s
99
+ }
100
+
101
+ // ExpandWildcards indicates whether to expand wildcard expression to
102
+ // concrete indices that are open, closed or both.
103
+ func (s * CountService ) ExpandWildcards (expandWildcards string ) * CountService {
104
+ s .expandWildcards = expandWildcards
54
105
return s
55
106
}
56
107
108
+ // IgnoreUnavailable indicates whether specified concrete indices should be
109
+ // ignored when unavailable (missing or closed).
110
+ func (s * CountService ) IgnoreUnavailable (ignoreUnavailable bool ) * CountService {
111
+ s .ignoreUnavailable = & ignoreUnavailable
112
+ return s
113
+ }
114
+
115
+ // Lenient specifies whether format-based query failures (such as
116
+ // providing text to a numeric field) should be ignored.
117
+ func (s * CountService ) Lenient (lenient bool ) * CountService {
118
+ s .lenient = & lenient
119
+ return s
120
+ }
121
+
122
+ // LowercaseExpandedTerms specifies whether query terms should be lowercased.
123
+ func (s * CountService ) LowercaseExpandedTerms (lowercaseExpandedTerms bool ) * CountService {
124
+ s .lowercaseExpandedTerms = & lowercaseExpandedTerms
125
+ return s
126
+ }
127
+
128
+ // MinScore indicates to include only documents with a specific `_score`
129
+ // value in the result.
130
+ func (s * CountService ) MinScore (minScore interface {}) * CountService {
131
+ s .minScore = minScore
132
+ return s
133
+ }
134
+
135
+ // Preference specifies the node or shard the operation should be
136
+ // performed on (default: random).
137
+ func (s * CountService ) Preference (preference string ) * CountService {
138
+ s .preference = preference
139
+ return s
140
+ }
141
+
142
+ // Q in the Lucene query string syntax. You can also use Query to pass
143
+ // a Query struct.
144
+ func (s * CountService ) Q (q string ) * CountService {
145
+ s .q = q
146
+ return s
147
+ }
148
+
149
+ // Query specifies the query to pass. You can also pass a query string with Q.
57
150
func (s * CountService ) Query (query Query ) * CountService {
58
151
s .query = query
59
152
return s
60
153
}
61
154
155
+ // Routing specifies the routing value.
156
+ func (s * CountService ) Routing (routing string ) * CountService {
157
+ s .routing = routing
158
+ return s
159
+ }
160
+
161
+ // Pretty indicates that the JSON response be indented and human readable.
62
162
func (s * CountService ) Pretty (pretty bool ) * CountService {
63
163
s .pretty = pretty
64
164
return s
65
165
}
66
166
67
- func (s * CountService ) Do () (int64 , error ) {
68
- var err error
167
+ // BodyJson specifies the query to restrict the results specified with the
168
+ // Query DSL (optional). The interface{} will be serialized to a JSON document,
169
+ // so use a map[string]interface{}.
170
+ func (s * CountService ) BodyJson (body interface {}) * CountService {
171
+ s .bodyJson = body
172
+ return s
173
+ }
69
174
70
- // Build url
71
- path := "/"
175
+ // Body specifies a query to restrict the results specified with
176
+ // the Query DSL (optional).
177
+ func (s * CountService ) BodyString (body string ) * CountService {
178
+ s .bodyString = body
179
+ return s
180
+ }
72
181
73
- // Indices part
74
- indexPart := make ([]string , 0 )
75
- for _ , index := range s .indices {
76
- index , err = uritemplates .Expand ("{index}" , map [string ]string {
77
- "index" : index ,
182
+ // buildURL builds the URL for the operation.
183
+ func (s * CountService ) buildURL () (string , url.Values , error ) {
184
+ var err error
185
+ var path string
186
+
187
+ if len (s .index ) > 0 && len (s .typ ) > 0 {
188
+ path , err = uritemplates .Expand ("/{index}/{type}/_count" , map [string ]string {
189
+ "index" : strings .Join (s .index , "," ),
190
+ "type" : strings .Join (s .typ , "," ),
78
191
})
79
- if err != nil {
80
- return 0 , err
81
- }
82
- indexPart = append (indexPart , index )
192
+ } else if len (s .index ) > 0 {
193
+ path , err = uritemplates .Expand ("/{index}/_count" , map [string ]string {
194
+ "index" : strings .Join (s .index , "," ),
195
+ })
196
+ } else if len (s .typ ) > 0 {
197
+ path , err = uritemplates .Expand ("/_all/{type}/_count" , map [string ]string {
198
+ "type" : strings .Join (s .typ , "," ),
199
+ })
200
+ } else {
201
+ path = "/_all/_count"
83
202
}
84
- if len ( indexPart ) > 0 {
85
- path += strings . Join ( indexPart , "," )
203
+ if err != nil {
204
+ return "" , url. Values {}, err
86
205
}
87
206
88
- // Types part
89
- typesPart := make ([]string , 0 )
90
- for _ , typ := range s .types {
91
- typ , err = uritemplates .Expand ("{type}" , map [string ]string {
92
- "type" : typ ,
93
- })
94
- if err != nil {
95
- return 0 , err
96
- }
97
- typesPart = append (typesPart , typ )
207
+ // Add query string parameters
208
+ params := url.Values {}
209
+ if s .pretty {
210
+ params .Set ("pretty" , "1" )
211
+ }
212
+ if s .allowNoIndices != nil {
213
+ params .Set ("allow_no_indices" , fmt .Sprintf ("%v" , * s .allowNoIndices ))
214
+ }
215
+ if s .analyzeWildcard != nil {
216
+ params .Set ("analyze_wildcard" , fmt .Sprintf ("%v" , * s .analyzeWildcard ))
217
+ }
218
+ if s .analyzer != "" {
219
+ params .Set ("analyzer" , s .analyzer )
220
+ }
221
+ if s .defaultOperator != "" {
222
+ params .Set ("default_operator" , s .defaultOperator )
98
223
}
99
- if len ( typesPart ) > 0 {
100
- path += "/" + strings . Join ( typesPart , "," )
224
+ if s . df != "" {
225
+ params . Set ( "df" , s . df )
101
226
}
227
+ if s .expandWildcards != "" {
228
+ params .Set ("expand_wildcards" , s .expandWildcards )
229
+ }
230
+ if s .ignoreUnavailable != nil {
231
+ params .Set ("ignore_unavailable" , fmt .Sprintf ("%v" , * s .ignoreUnavailable ))
232
+ }
233
+ if s .lenient != nil {
234
+ params .Set ("lenient" , fmt .Sprintf ("%v" , * s .lenient ))
235
+ }
236
+ if s .lowercaseExpandedTerms != nil {
237
+ params .Set ("lowercase_expanded_terms" , fmt .Sprintf ("%v" , * s .lowercaseExpandedTerms ))
238
+ }
239
+ if s .minScore != nil {
240
+ params .Set ("min_score" , fmt .Sprintf ("%v" , s .minScore ))
241
+ }
242
+ if s .preference != "" {
243
+ params .Set ("preference" , s .preference )
244
+ }
245
+ if s .q != "" {
246
+ params .Set ("q" , s .q )
247
+ }
248
+ if s .routing != "" {
249
+ params .Set ("routing" , s .routing )
250
+ }
251
+ return path , params , nil
252
+ }
102
253
103
- // Search
104
- path += "/_count"
254
+ // Validate checks if the operation is valid.
255
+ func (s * CountService ) Validate () error {
256
+ return nil
257
+ }
105
258
106
- // Parameters
107
- params := make (url.Values )
108
- if s .pretty {
109
- params .Set ("pretty" , fmt .Sprintf ("%v" , s .pretty ))
259
+ // Do executes the operation.
260
+ func (s * CountService ) Do () (int64 , error ) {
261
+ // Check pre-conditions
262
+ if err := s .Validate (); err != nil {
263
+ return 0 , err
264
+ }
265
+
266
+ // Get URL for request
267
+ path , params , err := s .buildURL ()
268
+ if err != nil {
269
+ return 0 , err
110
270
}
111
271
112
- // Set body if there is a query specified
272
+ // Setup HTTP request body
113
273
var body interface {}
114
274
if s .query != nil {
115
275
src , err := s .query .Source ()
@@ -119,16 +279,20 @@ func (s *CountService) Do() (int64, error) {
119
279
query := make (map [string ]interface {})
120
280
query ["query" ] = src
121
281
body = query
282
+ } else if s .bodyJson != nil {
283
+ body = s .bodyJson
284
+ } else if s .bodyString != "" {
285
+ body = s .bodyString
122
286
}
123
287
124
- // Get response
288
+ // Get HTTP response
125
289
res , err := s .client .PerformRequest ("POST" , path , params , body )
126
290
if err != nil {
127
291
return 0 , err
128
292
}
129
293
130
294
// Return result
131
- ret := new (CountResult )
295
+ ret := new (CountResponse )
132
296
if err := json .Unmarshal (res .Body , ret ); err != nil {
133
297
return 0 , err
134
298
}
@@ -138,3 +302,9 @@ func (s *CountService) Do() (int64, error) {
138
302
139
303
return int64 (0 ), nil
140
304
}
305
+
306
+ // CountResponse is the response of using the Count API.
307
+ type CountResponse struct {
308
+ Count int64 `json:"count"`
309
+ Shards shardsInfo `json:"_shards,omitempty"`
310
+ }
0 commit comments