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// InnerHit implements a simple join for parent/child, nested, and even
8// top-level documents in Elasticsearch.
9// It is an experimental feature for Elasticsearch versions 1.5 (or greater).
10// See http://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-request-inner-hits.html
11// for documentation.
12//
13// See the tests for SearchSource, HasChildFilter, HasChildQuery,
14// HasParentFilter, HasParentQuery, NestedFilter, and NestedQuery
15// for usage examples.
16type InnerHit struct {
17	source *SearchSource
18	path   string
19	typ    string
20
21	name string
22}
23
24// NewInnerHit creates a new InnerHit.
25func NewInnerHit() *InnerHit {
26	return &InnerHit{source: NewSearchSource()}
27}
28
29func (hit *InnerHit) Path(path string) *InnerHit {
30	hit.path = path
31	return hit
32}
33
34func (hit *InnerHit) Type(typ string) *InnerHit {
35	hit.typ = typ
36	return hit
37}
38
39func (hit *InnerHit) Query(query Query) *InnerHit {
40	hit.source.Query(query)
41	return hit
42}
43
44func (hit *InnerHit) From(from int) *InnerHit {
45	hit.source.From(from)
46	return hit
47}
48
49func (hit *InnerHit) Size(size int) *InnerHit {
50	hit.source.Size(size)
51	return hit
52}
53
54func (hit *InnerHit) TrackScores(trackScores bool) *InnerHit {
55	hit.source.TrackScores(trackScores)
56	return hit
57}
58
59func (hit *InnerHit) Explain(explain bool) *InnerHit {
60	hit.source.Explain(explain)
61	return hit
62}
63
64func (hit *InnerHit) Version(version bool) *InnerHit {
65	hit.source.Version(version)
66	return hit
67}
68
69func (hit *InnerHit) StoredField(storedFieldName string) *InnerHit {
70	hit.source.StoredField(storedFieldName)
71	return hit
72}
73
74func (hit *InnerHit) StoredFields(storedFieldNames ...string) *InnerHit {
75	hit.source.StoredFields(storedFieldNames...)
76	return hit
77}
78
79func (hit *InnerHit) NoStoredFields() *InnerHit {
80	hit.source.NoStoredFields()
81	return hit
82}
83
84func (hit *InnerHit) FetchSource(fetchSource bool) *InnerHit {
85	hit.source.FetchSource(fetchSource)
86	return hit
87}
88
89func (hit *InnerHit) FetchSourceContext(fetchSourceContext *FetchSourceContext) *InnerHit {
90	hit.source.FetchSourceContext(fetchSourceContext)
91	return hit
92}
93
94func (hit *InnerHit) DocvalueFields(docvalueFields ...string) *InnerHit {
95	hit.source.DocvalueFields(docvalueFields...)
96	return hit
97}
98
99func (hit *InnerHit) DocvalueField(docvalueField string) *InnerHit {
100	hit.source.DocvalueField(docvalueField)
101	return hit
102}
103
104func (hit *InnerHit) ScriptFields(scriptFields ...*ScriptField) *InnerHit {
105	hit.source.ScriptFields(scriptFields...)
106	return hit
107}
108
109func (hit *InnerHit) ScriptField(scriptField *ScriptField) *InnerHit {
110	hit.source.ScriptField(scriptField)
111	return hit
112}
113
114func (hit *InnerHit) Sort(field string, ascending bool) *InnerHit {
115	hit.source.Sort(field, ascending)
116	return hit
117}
118
119func (hit *InnerHit) SortWithInfo(info SortInfo) *InnerHit {
120	hit.source.SortWithInfo(info)
121	return hit
122}
123
124func (hit *InnerHit) SortBy(sorter ...Sorter) *InnerHit {
125	hit.source.SortBy(sorter...)
126	return hit
127}
128
129func (hit *InnerHit) Highlight(highlight *Highlight) *InnerHit {
130	hit.source.Highlight(highlight)
131	return hit
132}
133
134func (hit *InnerHit) Highlighter() *Highlight {
135	return hit.source.Highlighter()
136}
137
138func (hit *InnerHit) Name(name string) *InnerHit {
139	hit.name = name
140	return hit
141}
142
143func (hit *InnerHit) Source() (interface{}, error) {
144	src, err := hit.source.Source()
145	if err != nil {
146		return nil, err
147	}
148	source, ok := src.(map[string]interface{})
149	if !ok {
150		return nil, nil
151	}
152
153	// Notice that hit.typ and hit.path are not exported here.
154	// They are only used with SearchSource and serialized there.
155
156	if hit.name != "" {
157		source["name"] = hit.name
158	}
159	return source, nil
160}
161