1// Copyright 2012-2015 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// Matches documents with fields that have terms within a certain range.
8// For details, see:
9// http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-range-query.html
10type RangeQuery struct {
11	Query
12	name         string
13	from         *interface{}
14	to           *interface{}
15	timeZone     string
16	format       string
17	includeLower bool
18	includeUpper bool
19	boost        *float64
20	queryName    string
21}
22
23func NewRangeQuery(name string) RangeQuery {
24	q := RangeQuery{name: name, includeLower: true, includeUpper: true}
25	return q
26}
27
28// TimeZone allows for adjusting the from/to fields using a time zone.
29// Only valid for date fields.
30func (q RangeQuery) TimeZone(timeZone string) RangeQuery {
31	q.timeZone = timeZone
32	return q
33}
34
35// Format is a valid option for date fields in a Range query.
36func (q RangeQuery) Format(format string) RangeQuery {
37	q.format = format
38	return q
39}
40
41func (q RangeQuery) From(from interface{}) RangeQuery {
42	q.from = &from
43	return q
44}
45
46func (q RangeQuery) Gt(from interface{}) RangeQuery {
47	q.from = &from
48	q.includeLower = false
49	return q
50}
51
52func (q RangeQuery) Gte(from interface{}) RangeQuery {
53	q.from = &from
54	q.includeLower = true
55	return q
56}
57
58func (q RangeQuery) To(to interface{}) RangeQuery {
59	q.to = &to
60	return q
61}
62
63func (q RangeQuery) Lt(to interface{}) RangeQuery {
64	q.to = &to
65	q.includeUpper = false
66	return q
67}
68
69func (q RangeQuery) Lte(to interface{}) RangeQuery {
70	q.to = &to
71	q.includeUpper = true
72	return q
73}
74
75func (q RangeQuery) IncludeLower(includeLower bool) RangeQuery {
76	q.includeLower = includeLower
77	return q
78}
79
80func (q RangeQuery) IncludeUpper(includeUpper bool) RangeQuery {
81	q.includeUpper = includeUpper
82	return q
83}
84
85func (q RangeQuery) Boost(boost float64) RangeQuery {
86	q.boost = &boost
87	return q
88}
89
90func (q RangeQuery) QueryName(queryName string) RangeQuery {
91	q.queryName = queryName
92	return q
93}
94
95func (q RangeQuery) Source() interface{} {
96	// {
97	//   "range" : {
98	//     "name" : {
99	//       "..." : "..."
100	//     }
101	//   }
102	// }
103
104	source := make(map[string]interface{})
105
106	rangeQ := make(map[string]interface{})
107	source["range"] = rangeQ
108
109	params := make(map[string]interface{})
110	rangeQ[q.name] = params
111
112	params["from"] = q.from
113	params["to"] = q.to
114	if q.timeZone != "" {
115		params["time_zone"] = q.timeZone
116	}
117	if q.format != "" {
118		params["format"] = q.format
119	}
120	params["include_lower"] = q.includeLower
121	params["include_upper"] = q.includeUpper
122
123	if q.boost != nil {
124		rangeQ["boost"] = *q.boost
125	}
126
127	if q.queryName != "" {
128		rangeQ["_name"] = q.queryName
129	}
130
131	return source
132}
133