/**
* @return ElasticaQuery
*/
private function prepareQuery($params, $start = null, $limit = null)
{
$query = null;
$filter = null;
$sort = ['_score' => 'desc'];
// We'd like to search in both title and description for keywords
if (!empty($params['keywords'])) {
$query = new QueryString($params['keywords']);
$query->setDefaultOperator('AND')->setFields(['title', 'description']);
}
// Add location filter is location is selected from autosuggest
if (!empty($params['location_id'])) {
$location = Location::find($params['location_id']);
$filter = new GeoDistance('location', ['lat' => $location->lat, 'lon' => $location->lon], $params['radius'] . 'mi');
// Sort by nearest hit
$sort = ['_geo_distance' => ['jobs.location' => [(double) $location->lon, (double) $location->lat], 'order' => 'asc', 'unit' => 'mi']];
}
// If neither keyword nor location supplied, then return all
if (empty($params['keywords']) && empty($params['location_id'])) {
$query = new MatchAll();
}
// We need a filtered query
$elasticaQuery = new ElasticaQuery(new Filtered($query, $filter));
$elasticaQuery->addSort($sort);
// Offset and limits
if (!is_null($start) && !is_null($limit)) {
$elasticaQuery->setFrom($start)->setSize($limit);
}
// Set up the highlight
$elasticaQuery->setHighlight(['order' => 'score', 'fields' => ['title' => ['fragment_size' => 100], 'description' => ['fragment_size' => 200]]]);
return $elasticaQuery;
}