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// GeoDistanceFilter filters documents that include only hits that exists
8// within a specific distance from a geo point.
9//
10// For more details, see:
11// http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-geo-distance-filter.html
12type GeoDistanceFilter struct {
13	Filter
14	name         string
15	distance     string
16	lat          float64
17	lon          float64
18	geohash      string
19	distanceType string
20	optimizeBbox string
21	cache        *bool
22	cacheKey     string
23	filterName   string
24}
25
26// NewGeoDistanceFilter creates a new GeoDistanceFilter.
27func NewGeoDistanceFilter(name string) GeoDistanceFilter {
28	f := GeoDistanceFilter{name: name}
29	return f
30}
31
32func (f GeoDistanceFilter) Distance(distance string) GeoDistanceFilter {
33	f.distance = distance
34	return f
35}
36
37func (f GeoDistanceFilter) GeoPoint(point *GeoPoint) GeoDistanceFilter {
38	f.lat = point.Lat
39	f.lon = point.Lon
40	return f
41}
42
43func (f GeoDistanceFilter) Point(lat, lon float64) GeoDistanceFilter {
44	f.lat = lat
45	f.lon = lon
46	return f
47}
48
49func (f GeoDistanceFilter) Lat(lat float64) GeoDistanceFilter {
50	f.lat = lat
51	return f
52}
53
54func (f GeoDistanceFilter) Lon(lon float64) GeoDistanceFilter {
55	f.lon = lon
56	return f
57}
58
59func (f GeoDistanceFilter) GeoHash(geohash string) GeoDistanceFilter {
60	f.geohash = geohash
61	return f
62}
63
64func (f GeoDistanceFilter) DistanceType(distanceType string) GeoDistanceFilter {
65	f.distanceType = distanceType
66	return f
67}
68
69func (f GeoDistanceFilter) OptimizeBbox(optimizeBbox string) GeoDistanceFilter {
70	f.optimizeBbox = optimizeBbox
71	return f
72}
73
74func (f GeoDistanceFilter) Cache(cache bool) GeoDistanceFilter {
75	f.cache = &cache
76	return f
77}
78
79func (f GeoDistanceFilter) CacheKey(cacheKey string) GeoDistanceFilter {
80	f.cacheKey = cacheKey
81	return f
82}
83
84func (f GeoDistanceFilter) FilterName(filterName string) GeoDistanceFilter {
85	f.filterName = filterName
86	return f
87}
88
89// Creates the query source for the geo_distance filter.
90func (f GeoDistanceFilter) Source() interface{} {
91	// {
92	//   "geo_distance" : {
93	//       "distance" : "200km",
94	//       "pin.location" : {
95	//           "lat" : 40,
96	//           "lon" : -70
97	//       }
98	//   }
99	// }
100
101	source := make(map[string]interface{})
102
103	params := make(map[string]interface{})
104
105	if f.geohash != "" {
106		params[f.name] = f.geohash
107	} else {
108		location := make(map[string]interface{})
109		location["lat"] = f.lat
110		location["lon"] = f.lon
111		params[f.name] = location
112	}
113
114	if f.distance != "" {
115		params["distance"] = f.distance
116	}
117	if f.distanceType != "" {
118		params["distance_type"] = f.distanceType
119	}
120	if f.optimizeBbox != "" {
121		params["optimize_bbox"] = f.optimizeBbox
122	}
123	if f.cache != nil {
124		params["_cache"] = *f.cache
125	}
126	if f.cacheKey != "" {
127		params["_cache_key"] = f.cacheKey
128	}
129	if f.filterName != "" {
130		params["_name"] = f.filterName
131	}
132
133	source["geo_distance"] = params
134
135	return source
136}
137