@@ -7,24 +7,30 @@ package elastic
7
7
import "errors"
8
8
9
9
// CompletionSuggester is a fast suggester for e.g. type-ahead completion.
10
- // See https://www.elastic.co/guide/en/elasticsearch/reference/6.0 /search-suggesters-completion.html
10
+ // See https://www.elastic.co/guide/en/elasticsearch/reference/5.2 /search-suggesters-completion.html
11
11
// for more details.
12
12
type CompletionSuggester struct {
13
13
Suggester
14
14
name string
15
15
text string
16
+ prefix string
17
+ regex string
16
18
field string
17
19
analyzer string
18
20
size * int
19
21
shardSize * int
20
22
contextQueries []SuggesterContextQuery
23
+ payload interface {}
24
+
25
+ fuzzyOptions * FuzzyCompletionSuggesterOptions
26
+ regexOptions * RegexCompletionSuggesterOptions
27
+ skipDuplicates * bool
21
28
}
22
29
23
30
// Creates a new completion suggester.
24
31
func NewCompletionSuggester (name string ) * CompletionSuggester {
25
32
return & CompletionSuggester {
26
- name : name ,
27
- contextQueries : make ([]SuggesterContextQuery , 0 ),
33
+ name : name ,
28
34
}
29
35
}
30
36
@@ -37,6 +43,57 @@ func (q *CompletionSuggester) Text(text string) *CompletionSuggester {
37
43
return q
38
44
}
39
45
46
+ func (q * CompletionSuggester ) Prefix (prefix string ) * CompletionSuggester {
47
+ q .prefix = prefix
48
+ return q
49
+ }
50
+
51
+ func (q * CompletionSuggester ) PrefixWithEditDistance (prefix string , editDistance interface {}) * CompletionSuggester {
52
+ q .prefix = prefix
53
+ q .fuzzyOptions = NewFuzzyCompletionSuggesterOptions ().EditDistance (editDistance )
54
+ return q
55
+ }
56
+
57
+ func (q * CompletionSuggester ) PrefixWithOptions (prefix string , options * FuzzyCompletionSuggesterOptions ) * CompletionSuggester {
58
+ q .prefix = prefix
59
+ q .fuzzyOptions = options
60
+ return q
61
+ }
62
+
63
+ func (q * CompletionSuggester ) FuzzyOptions (options * FuzzyCompletionSuggesterOptions ) * CompletionSuggester {
64
+ q .fuzzyOptions = options
65
+ return q
66
+ }
67
+
68
+ func (q * CompletionSuggester ) Fuzziness (fuzziness interface {}) * CompletionSuggester {
69
+ if q .fuzzyOptions == nil {
70
+ q .fuzzyOptions = NewFuzzyCompletionSuggesterOptions ()
71
+ }
72
+ q .fuzzyOptions = q .fuzzyOptions .EditDistance (fuzziness )
73
+ return q
74
+ }
75
+
76
+ func (q * CompletionSuggester ) Regex (regex string ) * CompletionSuggester {
77
+ q .regex = regex
78
+ return q
79
+ }
80
+
81
+ func (q * CompletionSuggester ) RegexWithOptions (regex string , options * RegexCompletionSuggesterOptions ) * CompletionSuggester {
82
+ q .regex = regex
83
+ q .regexOptions = options
84
+ return q
85
+ }
86
+
87
+ func (q * CompletionSuggester ) RegexOptions (options * RegexCompletionSuggesterOptions ) * CompletionSuggester {
88
+ q .regexOptions = options
89
+ return q
90
+ }
91
+
92
+ func (q * CompletionSuggester ) SkipDuplicates (skipDuplicates bool ) * CompletionSuggester {
93
+ q .skipDuplicates = & skipDuplicates
94
+ return q
95
+ }
96
+
40
97
func (q * CompletionSuggester ) Field (field string ) * CompletionSuggester {
41
98
q .field = field
42
99
return q
@@ -72,17 +129,25 @@ func (q *CompletionSuggester) ContextQueries(queries ...SuggesterContextQuery) *
72
129
// We got into trouble when using plain maps because the text element
73
130
// needs to go before the completion element.
74
131
type completionSuggesterRequest struct {
75
- Text string `json:"text"`
76
- Completion interface {} `json:"completion"`
132
+ Text string `json:"text,omitempty"`
133
+ Prefix string `json:"prefix,omitempty"`
134
+ Regex string `json:"regex,omitempty"`
135
+ Completion interface {} `json:"completion,omitempty"`
77
136
}
78
137
79
- // Creates the source for the completion suggester.
138
+ // Source creates the JSON data for the completion suggester.
80
139
func (q * CompletionSuggester ) Source (includeName bool ) (interface {}, error ) {
81
140
cs := & completionSuggesterRequest {}
82
141
83
142
if q .text != "" {
84
143
cs .Text = q .text
85
144
}
145
+ if q .prefix != "" {
146
+ cs .Prefix = q .prefix
147
+ }
148
+ if q .regex != "" {
149
+ cs .Regex = q .regex
150
+ }
86
151
87
152
suggester := make (map [string ]interface {})
88
153
cs .Completion = suggester
@@ -126,6 +191,28 @@ func (q *CompletionSuggester) Source(includeName bool) (interface{}, error) {
126
191
suggester ["contexts" ] = ctxq
127
192
}
128
193
194
+ // Fuzzy options
195
+ if q .fuzzyOptions != nil {
196
+ src , err := q .fuzzyOptions .Source ()
197
+ if err != nil {
198
+ return nil , err
199
+ }
200
+ suggester ["fuzzy" ] = src
201
+ }
202
+
203
+ // Regex options
204
+ if q .regexOptions != nil {
205
+ src , err := q .regexOptions .Source ()
206
+ if err != nil {
207
+ return nil , err
208
+ }
209
+ suggester ["regex" ] = src
210
+ }
211
+
212
+ if q .skipDuplicates != nil {
213
+ suggester ["skip_duplicates" ] = * q .skipDuplicates
214
+ }
215
+
129
216
// TODO(oe) Add completion-suggester specific parameters here
130
217
131
218
if ! includeName {
@@ -136,3 +223,130 @@ func (q *CompletionSuggester) Source(includeName bool) (interface{}, error) {
136
223
source [q .name ] = cs
137
224
return source , nil
138
225
}
226
+
227
+ // -- Fuzzy options --
228
+
229
+ // FuzzyCompletionSuggesterOptions represents the options for fuzzy completion suggester.
230
+ type FuzzyCompletionSuggesterOptions struct {
231
+ editDistance interface {}
232
+ transpositions * bool
233
+ minLength * int
234
+ prefixLength * int
235
+ unicodeAware * bool
236
+ maxDeterminizedStates * int
237
+ }
238
+
239
+ // NewFuzzyCompletionSuggesterOptions initializes a new FuzzyCompletionSuggesterOptions instance.
240
+ func NewFuzzyCompletionSuggesterOptions () * FuzzyCompletionSuggesterOptions {
241
+ return & FuzzyCompletionSuggesterOptions {}
242
+ }
243
+
244
+ // EditDistance specifies the maximum number of edits, e.g. a number like "1" or "2"
245
+ // or a string like "0..2" or ">5". See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/common-options.html#fuzziness
246
+ // for details.
247
+ func (o * FuzzyCompletionSuggesterOptions ) EditDistance (editDistance interface {}) * FuzzyCompletionSuggesterOptions {
248
+ o .editDistance = editDistance
249
+ return o
250
+ }
251
+
252
+ // Transpositions, if set to true, are counted as one change instead of two (defaults to true).
253
+ func (o * FuzzyCompletionSuggesterOptions ) Transpositions (transpositions bool ) * FuzzyCompletionSuggesterOptions {
254
+ o .transpositions = & transpositions
255
+ return o
256
+ }
257
+
258
+ // MinLength represents the minimum length of the input before fuzzy suggestions are returned (defaults to 3).
259
+ func (o * FuzzyCompletionSuggesterOptions ) MinLength (minLength int ) * FuzzyCompletionSuggesterOptions {
260
+ o .minLength = & minLength
261
+ return o
262
+ }
263
+
264
+ // PrefixLength represents the minimum length of the input, which is not checked for
265
+ // fuzzy alternatives (defaults to 1).
266
+ func (o * FuzzyCompletionSuggesterOptions ) PrefixLength (prefixLength int ) * FuzzyCompletionSuggesterOptions {
267
+ o .prefixLength = & prefixLength
268
+ return o
269
+ }
270
+
271
+ // UnicodeAware, if true, all measurements (like fuzzy edit distance, transpositions, and lengths)
272
+ // are measured in Unicode code points instead of in bytes. This is slightly slower than
273
+ // raw bytes, so it is set to false by default.
274
+ func (o * FuzzyCompletionSuggesterOptions ) UnicodeAware (unicodeAware bool ) * FuzzyCompletionSuggesterOptions {
275
+ o .unicodeAware = & unicodeAware
276
+ return o
277
+ }
278
+
279
+ // MaxDeterminizedStates is currently undocumented in Elasticsearch. It represents
280
+ // the maximum automaton states allowed for fuzzy expansion.
281
+ func (o * FuzzyCompletionSuggesterOptions ) MaxDeterminizedStates (max int ) * FuzzyCompletionSuggesterOptions {
282
+ o .maxDeterminizedStates = & max
283
+ return o
284
+ }
285
+
286
+ // Source creates the JSON data.
287
+ func (o * FuzzyCompletionSuggesterOptions ) Source () (interface {}, error ) {
288
+ out := make (map [string ]interface {})
289
+
290
+ if o .editDistance != nil {
291
+ out ["fuzziness" ] = o .editDistance
292
+ }
293
+ if o .transpositions != nil {
294
+ out ["transpositions" ] = * o .transpositions
295
+ }
296
+ if o .minLength != nil {
297
+ out ["min_length" ] = * o .minLength
298
+ }
299
+ if o .prefixLength != nil {
300
+ out ["prefix_length" ] = * o .prefixLength
301
+ }
302
+ if o .unicodeAware != nil {
303
+ out ["unicode_aware" ] = * o .unicodeAware
304
+ }
305
+ if o .maxDeterminizedStates != nil {
306
+ out ["max_determinized_states" ] = * o .maxDeterminizedStates
307
+ }
308
+
309
+ return out , nil
310
+ }
311
+
312
+ // -- Regex options --
313
+
314
+ // RegexCompletionSuggesterOptions represents the options for regex completion suggester.
315
+ type RegexCompletionSuggesterOptions struct {
316
+ flags interface {} // string or int
317
+ maxDeterminizedStates * int
318
+ }
319
+
320
+ // NewRegexCompletionSuggesterOptions initializes a new RegexCompletionSuggesterOptions instance.
321
+ func NewRegexCompletionSuggesterOptions () * RegexCompletionSuggesterOptions {
322
+ return & RegexCompletionSuggesterOptions {}
323
+ }
324
+
325
+ // Flags represents internal regex flags. See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-suggesters-completion.html#regex
326
+ // for details.
327
+ func (o * RegexCompletionSuggesterOptions ) Flags (flags interface {}) * RegexCompletionSuggesterOptions {
328
+ o .flags = flags
329
+ return o
330
+ }
331
+
332
+ // MaxDeterminizedStates represents the maximum automaton states allowed for regex expansion.
333
+ // See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-suggesters-completion.html#regex
334
+ // for details.
335
+ func (o * RegexCompletionSuggesterOptions ) MaxDeterminizedStates (max int ) * RegexCompletionSuggesterOptions {
336
+ o .maxDeterminizedStates = & max
337
+ return o
338
+ }
339
+
340
+ // Source creates the JSON data.
341
+ func (o * RegexCompletionSuggesterOptions ) Source () (interface {}, error ) {
342
+ out := make (map [string ]interface {})
343
+
344
+ if o .flags != nil {
345
+ out ["flags" ] = o .flags
346
+ }
347
+ if o .maxDeterminizedStates != nil {
348
+ out ["max_determinized_states" ] = * o .maxDeterminizedStates
349
+ }
350
+
351
+ return out , nil
352
+ }
0 commit comments