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
7import (
8	"encoding/json"
9	"errors"
10)
11
12// SuggestField can be used by the caller to specify a suggest field
13// at index time. For a detailed example, see e.g.
14// https://www.elastic.co/blog/you-complete-me.
15type SuggestField struct {
16	inputs         []string
17	weight         int
18	contextQueries []SuggesterContextQuery
19}
20
21func NewSuggestField(input ...string) *SuggestField {
22	return &SuggestField{
23		inputs: input,
24		weight: -1,
25	}
26}
27
28func (f *SuggestField) Input(input ...string) *SuggestField {
29	if f.inputs == nil {
30		f.inputs = make([]string, 0)
31	}
32	f.inputs = append(f.inputs, input...)
33	return f
34}
35
36func (f *SuggestField) Weight(weight int) *SuggestField {
37	f.weight = weight
38	return f
39}
40
41func (f *SuggestField) ContextQuery(queries ...SuggesterContextQuery) *SuggestField {
42	f.contextQueries = append(f.contextQueries, queries...)
43	return f
44}
45
46// MarshalJSON encodes SuggestField into JSON.
47func (f *SuggestField) MarshalJSON() ([]byte, error) {
48	source := make(map[string]interface{})
49
50	if f.inputs != nil {
51		switch len(f.inputs) {
52		case 1:
53			source["input"] = f.inputs[0]
54		default:
55			source["input"] = f.inputs
56		}
57	}
58
59	if f.weight >= 0 {
60		source["weight"] = f.weight
61	}
62
63	switch len(f.contextQueries) {
64	case 0:
65	case 1:
66		src, err := f.contextQueries[0].Source()
67		if err != nil {
68			return nil, err
69		}
70		source["contexts"] = src
71	default:
72		ctxq := make(map[string]interface{})
73		for _, query := range f.contextQueries {
74			src, err := query.Source()
75			if err != nil {
76				return nil, err
77			}
78			m, ok := src.(map[string]interface{})
79			if !ok {
80				return nil, errors.New("SuggesterContextQuery must be of type map[string]interface{}")
81			}
82			for k, v := range m {
83				ctxq[k] = v
84			}
85		}
86		source["contexts"] = ctxq
87	}
88
89	return json.Marshal(source)
90}
91