1// Copyright 2012-present Oliver Eilhard. All rights reserved.
2// Use of this source code is governed by a MIT-license.
3// See http://olivere.mit-license.org/license.txt for details.
4
5package elastic
6
7// FuzzyFuzzyCompletionSuggester is a FuzzyCompletionSuggester that allows fuzzy
8// completion.
9// See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-suggesters-completion.html
10// for details, and
11// https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-suggesters-completion.html#fuzzy
12// for details about the fuzzy completion suggester.
13type FuzzyCompletionSuggester struct {
14	Suggester
15	name           string
16	text           string
17	field          string
18	analyzer       string
19	size           *int
20	shardSize      *int
21	contextQueries []SuggesterContextQuery
22
23	fuzziness           interface{}
24	fuzzyTranspositions *bool
25	fuzzyMinLength      *int
26	fuzzyPrefixLength   *int
27	unicodeAware        *bool
28}
29
30// Fuzziness defines the fuzziness which is used in FuzzyCompletionSuggester.
31type Fuzziness struct {
32}
33
34// Creates a new completion suggester.
35func NewFuzzyCompletionSuggester(name string) *FuzzyCompletionSuggester {
36	return &FuzzyCompletionSuggester{
37		name:           name,
38		contextQueries: make([]SuggesterContextQuery, 0),
39	}
40}
41
42func (q *FuzzyCompletionSuggester) Name() string {
43	return q.name
44}
45
46func (q *FuzzyCompletionSuggester) Text(text string) *FuzzyCompletionSuggester {
47	q.text = text
48	return q
49}
50
51func (q *FuzzyCompletionSuggester) Field(field string) *FuzzyCompletionSuggester {
52	q.field = field
53	return q
54}
55
56func (q *FuzzyCompletionSuggester) Analyzer(analyzer string) *FuzzyCompletionSuggester {
57	q.analyzer = analyzer
58	return q
59}
60
61func (q *FuzzyCompletionSuggester) Size(size int) *FuzzyCompletionSuggester {
62	q.size = &size
63	return q
64}
65
66func (q *FuzzyCompletionSuggester) ShardSize(shardSize int) *FuzzyCompletionSuggester {
67	q.shardSize = &shardSize
68	return q
69}
70
71func (q *FuzzyCompletionSuggester) ContextQuery(query SuggesterContextQuery) *FuzzyCompletionSuggester {
72	q.contextQueries = append(q.contextQueries, query)
73	return q
74}
75
76func (q *FuzzyCompletionSuggester) ContextQueries(queries ...SuggesterContextQuery) *FuzzyCompletionSuggester {
77	q.contextQueries = append(q.contextQueries, queries...)
78	return q
79}
80
81// Fuzziness defines the strategy used to describe what "fuzzy" actually
82// means for the suggester, e.g. 1, 2, "0", "1..2", ">4", or "AUTO".
83// See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/common-options.html#fuzziness
84// for a detailed description.
85func (q *FuzzyCompletionSuggester) Fuzziness(fuzziness interface{}) *FuzzyCompletionSuggester {
86	q.fuzziness = fuzziness
87	return q
88}
89
90func (q *FuzzyCompletionSuggester) FuzzyTranspositions(fuzzyTranspositions bool) *FuzzyCompletionSuggester {
91	q.fuzzyTranspositions = &fuzzyTranspositions
92	return q
93}
94
95func (q *FuzzyCompletionSuggester) FuzzyMinLength(minLength int) *FuzzyCompletionSuggester {
96	q.fuzzyMinLength = &minLength
97	return q
98}
99
100func (q *FuzzyCompletionSuggester) FuzzyPrefixLength(prefixLength int) *FuzzyCompletionSuggester {
101	q.fuzzyPrefixLength = &prefixLength
102	return q
103}
104
105func (q *FuzzyCompletionSuggester) UnicodeAware(unicodeAware bool) *FuzzyCompletionSuggester {
106	q.unicodeAware = &unicodeAware
107	return q
108}
109
110// Creates the source for the completion suggester.
111func (q *FuzzyCompletionSuggester) Source(includeName bool) (interface{}, error) {
112	cs := &completionSuggesterRequest{}
113
114	if q.text != "" {
115		cs.Text = q.text
116	}
117
118	suggester := make(map[string]interface{})
119	cs.Completion = suggester
120
121	if q.analyzer != "" {
122		suggester["analyzer"] = q.analyzer
123	}
124	if q.field != "" {
125		suggester["field"] = q.field
126	}
127	if q.size != nil {
128		suggester["size"] = *q.size
129	}
130	if q.shardSize != nil {
131		suggester["shard_size"] = *q.shardSize
132	}
133	switch len(q.contextQueries) {
134	case 0:
135	case 1:
136		src, err := q.contextQueries[0].Source()
137		if err != nil {
138			return nil, err
139		}
140		suggester["context"] = src
141	default:
142		var ctxq []interface{}
143		for _, query := range q.contextQueries {
144			src, err := query.Source()
145			if err != nil {
146				return nil, err
147			}
148			ctxq = append(ctxq, src)
149		}
150		suggester["context"] = ctxq
151	}
152
153	// Fuzzy Completion Suggester fields
154	fuzzy := make(map[string]interface{})
155	suggester["fuzzy"] = fuzzy
156	if q.fuzziness != nil {
157		fuzzy["fuzziness"] = q.fuzziness
158	}
159	if q.fuzzyTranspositions != nil {
160		fuzzy["transpositions"] = *q.fuzzyTranspositions
161	}
162	if q.fuzzyMinLength != nil {
163		fuzzy["min_length"] = *q.fuzzyMinLength
164	}
165	if q.fuzzyPrefixLength != nil {
166		fuzzy["prefix_length"] = *q.fuzzyPrefixLength
167	}
168	if q.unicodeAware != nil {
169		fuzzy["unicode_aware"] = *q.unicodeAware
170	}
171
172	if !includeName {
173		return cs, nil
174	}
175
176	source := make(map[string]interface{})
177	source[q.name] = cs
178	return source, nil
179}
180