### Use Case

I want to retrieve locations

- that are
**within the NYC area**, defined by a rectangular viewport

- and
**boost those that are in Brooklyn**, described by a GeoJSON polygon:

### Approach

#### Data

## Let's create an index:

```
PUT locations
{
"mappings": {
"properties": {
"geometry": {
"type": "object",
"properties": {
"coordinates": {
"type": "geo_point"
}
}
}
}
}
}
```

Notice how the

`geometry.coordinates`

field **is explicitly declared as a****. It's tempting to use the**`geo_point`

`geo_shape`

field type on the whole `geometry`

field because a `Point`

is a valid GeoJSON type (which a `geo_shape`

would accept) but the `geo_bounding_box`

query we'll be using only allows filtering on explicitly declared `geo_point`

fields!## Next, let's add some locations into our index:

```
POST _bulk
{"index":{"_index":"locations"}}
{"geometry":{"type":"Point","coordinates":[-73.78964,40.70269]}}
{"index":{"_index":"locations"}}
{"geometry":{"type":"Point","coordinates":[-74.14181,40.76044]}}
{"index":{"_index":"locations"}}
{"geometry":{"type":"Point","coordinates":[-74.18276,40.85367]}}
{"index":{"_index":"locations"}}
{"geometry":{"type":"Point","coordinates":[-74.12306,40.62101]}}
{"index":{"_index":"locations"}}
{"geometry":{"type":"Point","coordinates":[-74.0113,40.83436]}}
{"index":{"_index":"locations"}}
{"geometry":{"type":"Point","coordinates":[-74.27228,40.72379]}}
{"index":{"_index":"locations"}}
{"geometry":{"type":"Point","coordinates":[-73.7888,40.59183]}}
{"index":{"_index":"locations"}}
{"geometry":{"type":"Point","coordinates":[-73.87138,40.86417]}}
{"index":{"_index":"locations"}}
{"geometry":{"type":"Point","coordinates":[-73.89522,40.71144]}}
{"index":{"_index":"locations"}}
{"geometry":{"type":"Point","coordinates":[-74.12918,40.72388]}}
{"index":{"_index":"locations"}}
{"geometry":{"type":"Point","coordinates":[-74.04345,40.86526]}}
{"index":{"_index":"locations"}}
{"geometry":{"type":"Point","coordinates":[-74.27225,40.84098]}}
{"index":{"_index":"locations"}}
{"geometry":{"type":"Point","coordinates":[-74.19762,40.69674]}}
{"index":{"_index":"locations"}}
{"geometry":{"type":"Point","coordinates":[-73.78374,40.89914]}}
{"index":{"_index":"locations"}}
{"geometry":{"type":"Point","coordinates":[-74.23609,40.86037]}}
{"index":{"_index":"locations"}}
{"geometry":{"type":"Point","coordinates":[-73.94215,40.67004]}}
{"index":{"_index":"locations"}}
{"geometry":{"type":"Point","coordinates":[-74.12929,40.60387]}}
{"index":{"_index":"locations"}}
{"geometry":{"type":"Point","coordinates":[-74.08588,40.68269]}}
{"index":{"_index":"locations"}}
{"geometry":{"type":"Point","coordinates":[-74.27447,40.89801]}}
{"index":{"_index":"locations"}}
{"geometry":{"type":"Point","coordinates":[-77.17435,38.98741]}, "meta": "not in nyc"}
```

#### Bounding Box Recap

In order to describe an area of a map (that uses the Mercator projection) with minimum points, we'll need a rectangle's

**opposing corners**— typically the south west and the north east:- South West → Bottom Left → [ min(x), min(y) ]

- North East → Top Right → [ max(x), max(y) ]

Many frontend mapping libraries implement a

`getBounds()`

method which returns the viewport's NE & SW corners — most notably Mapbox, Google Maps, and Leaflet.As soon as we've obtained the two points, we can plug them into the

`geo_bounding_box`

query:```
POST locations/_search
{
"query": {
"geo_bounding_box": {
"geometry.coordinates": {
"bottom_left": [-74.32457, 40.51119],
"top_right": [-73.72444, 40.93012]
}
}
}
}
```

*A bounding box encompassing the NYC area*

Alternatively, the opposing points' coordinates can be deconstructed into a

**bounding box**: