Geo Queries
Geo queries allow you to search for documents based on geographic locations. The elasticsearch-php-client supports various geo queries for different use cases.
Geo Distance Query
Finds documents within a certain distance from a point:
<?php
use Zvonchuk\Elastic\Query\QueryBuilders;
$query = QueryBuilders::GeoDistanceQuery('location')
->point(40.7128, -74.0060) // latitude, longitude
->distance('10km');
This generates:
{
"geo_distance": {
"distance": "10km",
"location": "40.7128,-74.0060"
}
}
Geo Bounding Box Query
Finds documents with geo-points within a bounding box:
<?php
use Zvonchuk\Elastic\Query\QueryBuilders;
$query = QueryBuilders::geoBoundingBoxQuery('location')
->topLeft(42.0, -72.0)
->bottomRight(40.0, -74.0);
Alternatively, you can use the bounding method:
<?php
use Zvonchuk\Elastic\Query\QueryBuilders;
$query = QueryBuilders::geoBoundingBoxQuery('location')
->bounding([
'top_left' => [42.0, -72.0],
'bottom_right' => [40.0, -74.0]
]);
This generates:
{
"geo_bounding_box": {
"location": {
"top_left": [42.0, -72.0],
"bottom_right": [40.0, -74.0]
}
}
}
Combining Geo Queries with Other Query Types
Geo queries can be combined with other query types using a bool query:
<?php
use Zvonchuk\Elastic\Query\QueryBuilders;
$boolQuery = QueryBuilders::boolQuery()
->must(QueryBuilders::matchQuery('category', 'restaurant'))
->filter(
QueryBuilders::GeoDistanceQuery('location')
->point(40.7128, -74.0060)
->distance('5km')
);
Example: Finding Nearby Restaurants
Here’s a complete example of using geo distance to find nearby restaurants:
<?php
use Zvonchuk\Elastic\Core\SearchRequest;
use Zvonchuk\Elastic\Search\Builder\SearchSourceBuilder;
use Zvonchuk\Elastic\Query\QueryBuilders;
use Zvonchuk\Elastic\Search\Sort\SortBuilders;
// Create a query for restaurants within 5km
$boolQuery = QueryBuilders::boolQuery()
->must(QueryBuilders::matchQuery('type', 'restaurant'))
->filter(
QueryBuilders::GeoDistanceQuery('location')
->point(40.7128, -74.0060) // New York City coordinates
->distance('5km')
);
// Set up the search with sorting by distance
$searchSource = new SearchSourceBuilder();
$searchSource->query($boolQuery);
$searchSource->sort(
SortBuilders::geoDistanceSort('location', 40.7128, -74.0060)
->order('asc') // closest first
->unit('km')
);
// Execute the search
$request = new SearchRequest('places');
$request->source($searchSource);
$response = $client->search($request);
// Process results
foreach ($response->getHits() as $hit) {
$name = $hit['_source']['name'];
$distance = isset($hit['sort'][0]) ? round($hit['sort'][0], 2) . 'km' : 'unknown';
echo "Restaurant: {$name}, Distance: {$distance}\n";
}