summaryrefslogtreecommitdiffstats
path: root/vendor/gopkg.in/olivere/elastic.v5/search_queries_geo_bounding_box.go
blob: 0418620d8ddb92c954c714f5a312eef55cb5a65a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// Copyright 2012-present Oliver Eilhard. All rights reserved.
// Use of this source code is governed by a MIT-license.
// See http://olivere.mit-license.org/license.txt for details.

package elastic

import "errors"

// GeoBoundingBoxQuery allows to filter hits based on a point location using
// a bounding box.
//
// For more details, see:
// https://www.elastic.co/guide/en/elasticsearch/reference/6.0/query-dsl-geo-bounding-box-query.html
type GeoBoundingBoxQuery struct {
	name      string
	top       *float64
	left      *float64
	bottom    *float64
	right     *float64
	typ       string
	queryName string
}

// NewGeoBoundingBoxQuery creates and initializes a new GeoBoundingBoxQuery.
func NewGeoBoundingBoxQuery(name string) *GeoBoundingBoxQuery {
	return &GeoBoundingBoxQuery{
		name: name,
	}
}

func (q *GeoBoundingBoxQuery) TopLeft(top, left float64) *GeoBoundingBoxQuery {
	q.top = &top
	q.left = &left
	return q
}

func (q *GeoBoundingBoxQuery) TopLeftFromGeoPoint(point *GeoPoint) *GeoBoundingBoxQuery {
	return q.TopLeft(point.Lat, point.Lon)
}

func (q *GeoBoundingBoxQuery) BottomRight(bottom, right float64) *GeoBoundingBoxQuery {
	q.bottom = &bottom
	q.right = &right
	return q
}

func (q *GeoBoundingBoxQuery) BottomRightFromGeoPoint(point *GeoPoint) *GeoBoundingBoxQuery {
	return q.BottomRight(point.Lat, point.Lon)
}

func (q *GeoBoundingBoxQuery) BottomLeft(bottom, left float64) *GeoBoundingBoxQuery {
	q.bottom = &bottom
	q.left = &left
	return q
}

func (q *GeoBoundingBoxQuery) BottomLeftFromGeoPoint(point *GeoPoint) *GeoBoundingBoxQuery {
	return q.BottomLeft(point.Lat, point.Lon)
}

func (q *GeoBoundingBoxQuery) TopRight(top, right float64) *GeoBoundingBoxQuery {
	q.top = &top
	q.right = &right
	return q
}

func (q *GeoBoundingBoxQuery) TopRightFromGeoPoint(point *GeoPoint) *GeoBoundingBoxQuery {
	return q.TopRight(point.Lat, point.Lon)
}

// Type sets the type of executing the geo bounding box. It can be either
// memory or indexed. It defaults to memory.
func (q *GeoBoundingBoxQuery) Type(typ string) *GeoBoundingBoxQuery {
	q.typ = typ
	return q
}

func (q *GeoBoundingBoxQuery) QueryName(queryName string) *GeoBoundingBoxQuery {
	q.queryName = queryName
	return q
}

// Source returns JSON for the function score query.
func (q *GeoBoundingBoxQuery) Source() (interface{}, error) {
	// {
	//   "geo_bounding_box" : {
	//     ...
	//   }
	// }

	if q.top == nil {
		return nil, errors.New("geo_bounding_box requires top latitude to be set")
	}
	if q.bottom == nil {
		return nil, errors.New("geo_bounding_box requires bottom latitude to be set")
	}
	if q.right == nil {
		return nil, errors.New("geo_bounding_box requires right longitude to be set")
	}
	if q.left == nil {
		return nil, errors.New("geo_bounding_box requires left longitude to be set")
	}

	source := make(map[string]interface{})
	params := make(map[string]interface{})
	source["geo_bounding_box"] = params

	box := make(map[string]interface{})
	box["top_left"] = []float64{*q.left, *q.top}
	box["bottom_right"] = []float64{*q.right, *q.bottom}
	params[q.name] = box

	if q.typ != "" {
		params["type"] = q.typ
	}
	if q.queryName != "" {
		params["_name"] = q.queryName
	}

	return source, nil
}