ElasticSearch - сортировка по расстоянию от точки

290
08 апреля 2017, 00:45

Я использую Elasticsearch для поиска заведений по названию. Мне нужно отсортировать результаты по количеству совпадений (_score) и расстоянию до координат человека (_geo_distance). Отсортировать по _score я могу. Получаю при поиске по названию такой примерно результат

Array
(
    [took] => 23
    [timed_out] => 
    [_shards] => Array
        (
            [total] => 5
            [successful] => 5
            [failed] => 0
        )
    [hits] => Array
        (
            [total] => 469
            [max_score] => 5.350864
            [hits] => Array
                (
                    [0] => Array
                        (
                            [_index] => salon
                            [_type] => services
                            [_id] => 7686
                            [_score] => 5.350864
                            [_source] => Array
                                (
                                    [service_name] => Found a string 1
                                    [service_id] => 10493
                                    [location] => Array
                                        (
                                            [lat] => 55.701328
                                            [lon] => 37.507412
                                        )
                                )
                        )
                    [1] => Array
                        (
                            [_index] => salon
                            [_type] => services
                            [_id] => 8350
                            [_score] => 5.350864
                            [_source] => Array
                                (
                                    [service_name] => Found a string 2
                                    [service_id] => 11171
                                    [location] => Array
                                        (
                                            [lat] => 55.869915
                                            [lon] => 37.613728
                                        )
                                )
                        )
                    [2] => Array
                        (
                            [_index] => salon
                            [_type] => services
                            [_id] => 14883
                            [_score] => 5.237593
                            [_source] => Array
                                (
                                    [service_name] => Found a string 3
                                    [service_id] => 17851
                                    [location] => Array
                                        (
                                            [lat] => 55.691734
                                            [lon] => 37.728164
                                        )
                                )
                        )
...

Но как еще отсортировать и по удалению от координат, например по расстоянию от точки 55.69,37.72? Я использую такой код для поиска

require 'vendor/autoload.php';
function searchES($word) {
    $client = \Elasticsearch\ClientBuilder::create()->setHosts([ES_HOST])->build();
    $IDs = [];
    $params = [];
    $params['index'] = ES_INDEX;
    if ($client->indices()->exists($params)) {
        $params['type'] = ES_TYPE;
        $params['size'] = 10000;
        $params['body']['sort'] = ['_score' => 'desc'];
        $params['body']['query']['match']['service_name'] = trim($word);

        $result = $client->search($params);
        if ($result['hits']['total'] > 0) {
            $result = $result['hits']['hits'];
            foreach ($result as $val) {
                $k = $val['_source']['service_id'];
                $IDs[$k] = $val['_source']['service_name'];
            }
        }
    }
    return $IDs;
}

А вот параметры которые использую для с создания индекса:

Array
(
    [index] => salon
    [body] => Array
        (
            [settings] => Array
                (
                    [analysis] => Array
                        (
                            [filter] => Array
                                (
                                    [ru_stop] => Array
                                        (
                                            [type] => stop
                                            [stopwords] => _russian_
                                        )
                                    [ru_stemmer] => Array
                                        (
                                            [type] => stemmer
                                            [language] => russian
                                        )
                                )
                            [analyzer] => Array
                                (
                                    [default] => Array
                                        (
                                            [tokenizer] => standard
                                            [filter] => Array
                                                (
                                                    [0] => lowercase
                                                    [1] => ru_stop
                                                    [2] => ru_stemmer
                                                )
                                        )
                                )
                        )
                )
            [mappings] => Array
                (
                    [_default_] => Array
                        (
                            [properties] => Array
                                (
                                    [service_name] => Array
                                        (
                                            [type] => string
                                            [analyzer] => default
                                        )
                                )
                        )
                )
        )
)
READ ALSO
Проверка ряда значений через empty

Проверка ряда значений через empty

Есть задача: нужно проверить на предмет наличия значений в ряде переменныхЕсть ли какой-то "человеческий" способ или каждую нужно перебирать...

215
Скрипт лайков на WordPress + Ajax

Скрипт лайков на WordPress + Ajax

Пытаюсь без сторонних плагинов сделать лайкиТак чтобы нажал один раз - "+1" лайк, нажал второй раз - "-1" лайк

326
Запись в массив

Запись в массив

Есть такой функционал

214
Laravel мультиязычность

Laravel мультиязычность

Добрый вечерОпыта в ларе не много

388