search_facets_geo_distance.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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. package elastic
  5. // The geo_distance facet is a facet providing information for ranges of
  6. // distances from a provided geo_point including count of the number of hits
  7. // that fall within each range, and aggregation information (like total).
  8. // See: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-geo-distance-facet.html
  9. type GeoDistanceFacet struct {
  10. facetFilter Filter
  11. global *bool
  12. nested string
  13. mode string
  14. fieldName string
  15. valueFieldName string
  16. lat float64
  17. lon float64
  18. geoHash string
  19. geoDistance string
  20. unit string
  21. params map[string]interface{}
  22. valueScript string
  23. lang string
  24. entries []geoDistanceFacetEntry
  25. }
  26. func NewGeoDistanceFacet() GeoDistanceFacet {
  27. return GeoDistanceFacet{
  28. params: make(map[string]interface{}),
  29. entries: make([]geoDistanceFacetEntry, 0),
  30. }
  31. }
  32. func (f GeoDistanceFacet) FacetFilter(filter Facet) GeoDistanceFacet {
  33. f.facetFilter = filter
  34. return f
  35. }
  36. func (f GeoDistanceFacet) Global(global bool) GeoDistanceFacet {
  37. f.global = &global
  38. return f
  39. }
  40. func (f GeoDistanceFacet) Nested(nested string) GeoDistanceFacet {
  41. f.nested = nested
  42. return f
  43. }
  44. func (f GeoDistanceFacet) Mode(mode string) GeoDistanceFacet {
  45. f.mode = mode
  46. return f
  47. }
  48. func (f GeoDistanceFacet) Field(fieldName string) GeoDistanceFacet {
  49. f.fieldName = fieldName
  50. return f
  51. }
  52. func (f GeoDistanceFacet) ValueField(valueFieldName string) GeoDistanceFacet {
  53. f.valueFieldName = valueFieldName
  54. return f
  55. }
  56. func (f GeoDistanceFacet) ValueScript(valueScript string) GeoDistanceFacet {
  57. f.valueScript = valueScript
  58. return f
  59. }
  60. func (f GeoDistanceFacet) Lang(lang string) GeoDistanceFacet {
  61. f.lang = lang
  62. return f
  63. }
  64. func (f GeoDistanceFacet) ScriptParam(name string, value interface{}) GeoDistanceFacet {
  65. f.params[name] = value
  66. return f
  67. }
  68. func (f GeoDistanceFacet) Point(lat, lon float64) GeoDistanceFacet {
  69. f.lat = lat
  70. f.lon = lon
  71. return f
  72. }
  73. func (f GeoDistanceFacet) Lat(lat float64) GeoDistanceFacet {
  74. f.lat = lat
  75. return f
  76. }
  77. func (f GeoDistanceFacet) Lon(lon float64) GeoDistanceFacet {
  78. f.lon = lon
  79. return f
  80. }
  81. func (f GeoDistanceFacet) GeoHash(geoHash string) GeoDistanceFacet {
  82. f.geoHash = geoHash
  83. return f
  84. }
  85. func (f GeoDistanceFacet) GeoDistance(geoDistance string) GeoDistanceFacet {
  86. f.geoDistance = geoDistance
  87. return f
  88. }
  89. func (f GeoDistanceFacet) AddRange(from, to float64) GeoDistanceFacet {
  90. f.entries = append(f.entries, geoDistanceFacetEntry{From: from, To: to})
  91. return f
  92. }
  93. func (f GeoDistanceFacet) AddUnboundedTo(from float64) GeoDistanceFacet {
  94. f.entries = append(f.entries, geoDistanceFacetEntry{From: from, To: nil})
  95. return f
  96. }
  97. func (f GeoDistanceFacet) AddUnboundedFrom(to float64) GeoDistanceFacet {
  98. f.entries = append(f.entries, geoDistanceFacetEntry{From: nil, To: to})
  99. return f
  100. }
  101. func (f GeoDistanceFacet) Unit(distanceUnit string) GeoDistanceFacet {
  102. f.unit = distanceUnit
  103. return f
  104. }
  105. func (f GeoDistanceFacet) addFilterFacetAndGlobal(source map[string]interface{}) {
  106. if f.facetFilter != nil {
  107. source["facet_filter"] = f.facetFilter.Source()
  108. }
  109. if f.nested != "" {
  110. source["nested"] = f.nested
  111. }
  112. if f.global != nil {
  113. source["global"] = *f.global
  114. }
  115. if f.mode != "" {
  116. source["mode"] = f.mode
  117. }
  118. }
  119. func (f GeoDistanceFacet) Source() interface{} {
  120. source := make(map[string]interface{})
  121. f.addFilterFacetAndGlobal(source)
  122. opts := make(map[string]interface{})
  123. source["geo_distance"] = opts
  124. if f.geoHash != "" {
  125. opts[f.fieldName] = f.geoHash
  126. } else {
  127. opts[f.fieldName] = []float64{f.lat, f.lon}
  128. }
  129. if f.valueFieldName != "" {
  130. opts["value_field"] = f.valueFieldName
  131. }
  132. if f.valueScript != "" {
  133. opts["value_script"] = f.valueScript
  134. if f.lang != "" {
  135. opts["lang"] = f.lang
  136. }
  137. if len(f.params) > 0 {
  138. opts["params"] = f.params
  139. }
  140. }
  141. ranges := make([]interface{}, 0)
  142. for _, ent := range f.entries {
  143. r := make(map[string]interface{})
  144. if ent.From != nil {
  145. switch from := ent.From.(type) {
  146. case int, int16, int32, int64, float32, float64:
  147. r["from"] = from
  148. case string:
  149. r["from"] = from
  150. }
  151. }
  152. if ent.To != nil {
  153. switch to := ent.To.(type) {
  154. case int, int16, int32, int64, float32, float64:
  155. r["to"] = to
  156. case string:
  157. r["to"] = to
  158. }
  159. }
  160. ranges = append(ranges, r)
  161. }
  162. opts["ranges"] = ranges
  163. if f.unit != "" {
  164. opts["unit"] = f.unit
  165. }
  166. if f.geoDistance != "" {
  167. opts["distance_type"] = f.geoDistance
  168. }
  169. return source
  170. }
  171. type geoDistanceFacetEntry struct {
  172. From interface{}
  173. To interface{}
  174. }