2017-01-30 2 views
1

Я работаю с ElasticSearch для приложения, которое имеет дело с «сообщениями». В настоящее время я работаю с geo_point, чтобы он возвращал все сообщения, упорядоченные по расстоянию от конечного пользователя. Хотя это работает, мне также необходимо работать в еще одном аспекте для системы.Игнорировать результаты за пределами допустимого диапазона

Должности могут быть оплачены и, например, если я должен был заплатить за свой пост и выбрать «Местный» в качестве диапазона площади, то этот пост должен показывать только конечным пользователям, которые меньше или равны 20 милям.

У меня есть столбец моего индекса с именем spotlight_range, есть ли способ создать запрос, чтобы сказать игнорировать все записи, если spotlight_range = 'Local' и расстояние> 20 миль? Мне нужно сделать это для нескольких диапазонов прожекторов. Например Региональный может быть 100 миль или меньше, и т.д.

Мой текущий запрос выглядит следующим образом

$params = [ 
    'index' => 'my_index', 
    'type' => 'posts', 
    'size' => 25, 
    'from' => 0, 
    'body' => [ 
     'sort' => [ 
      '_geo_distance' => [ 
       'post_location' => [ 
        'lat' => '44.4759', 
        'lon' => '-73.2121' 
       ], 
       'order' => 'asc', 
       'unit' => 'mi' 
      ] 
     ], 
     'query' => [ 
      'filtered' => [ 
       'query' => [ 
        'match_all' => [] 
       ], 
       'filter' => [ 
        'geo_distance' => [ 
         'distance' => '100mi', 
         'post_location' => [ 
          'lat' => '44.4759', 
          'lon' => '-73.2121' 
         ] 
        ] 
       ] 
      ] 
     ] 
    ] 
]; 

Мой индекс настроен со следующими полями.

'id' => ['type' => 'integer'], 
'title' => ['type' => 'string'], 
'description' => ['type' => 'string'], 
'price' => ['type' => 'integer'], 
'shippable' => ['type' => 'boolean'], 
'username' => ['type' => 'string'], 
'post_location' => ['type' => 'geo_point'], 
'post_location_string' => ['type' => 'string'], 
'is_spotlight' => ['type' => 'boolean'], 
'spotlight_range' => ['type' => 'string'], 
'created_at' => ['type' => 'date', 'format' => 'yyyy-MM-dd HH:mm:ss'], 
'updated_at' => ['type' => 'date', 'format' => 'yyyy-MM-dd HH:mm:ss'] 

Моя конечная цель для этого специально не искать расстояние < X и Y = диапазон, а чтобы он фильтровать их для всех типов на основе расстояния я указать. Поиск должен возвращать ВСЕ типы диапазонов, но также отфильтровывать что-либо за моим заданным расстоянием для каждого типа диапазона на основе пользователей lat/lon, переданных в запрос.

Я искал решение для этого онлайн без большой удачи.

+0

не могли бы вы добавить еще один пример, чтобы объяснить ваш прецедент? – user3775217

+0

У меня нет ничего более того, что я могу добавить в качестве примера, но я могу попытаться объяснить лучше. В настоящее время мы имеем значения для этих строк в файлах конфигурации, чтобы их можно было легко обновить. Местный = 20 миль, Региональный = 200 миль, национальный = 3000 миль и по всему миру = 250000 миль. Если, например, я запрашиваю у пользователей lat/lon любую запись, которая составляет> 20 миль и помеченная локалью не будет отображаться для этого конкретного пользователя, я бы хотел, чтобы они были отфильтрованы из результатов поиска. Я знаю, что могу это сделать, отправляя запросы на ES, но я не думаю, что это оптимально для получения записей, которые мне нужно будет отфильтровать. –

+0

То же самое касается Регионального, любое сообщение, которое находится на расстоянии 200 миль от местоположения пользователя lat/lon, должно быть отфильтровано из результатов. Я просто не уверен, как перевести это в ES-запрос, и я не нахожу многого в этой теме в Google или в любой книге ES, которую я просмотрел. –

ответ

0

Я бы добавил в документ круг geo_shape, ориентированный на post_location и с радиусом, соответствующим spotlight_range, так как вы знаете как информацию во время индексации. Таким образом, вы можете кодировать в каждый пост свой соответствующий «охват».

... 
'post_location' => ['type' => 'geo_point'], 
'spotlight_range' => ['type' => 'string'], 
'reach' => ['type' => 'geo_shape'],   <---- add this 

Так что «местный» документ будет выглядеть примерно так, как только индексируются

{ 
    "spotlight_range": "local", 
    "post_location": { 
     "lat": 42.1526, 
     "lon": -71.7378 
    }, 
    "reach" : { 
     "type" : "circle", 
     "coordinates" : [-71.7378, 42.1526], 
     "radius" : "20mi" 
    } 
} 

Тогда запрос будет выступать другой geo_shape сосредоточенный на местоположении пользователя с выбранным радиусом и будет только получить документы, которые reach пересекает форму круга в запросе.

$params = [ 
    'index' => 'my_index', 
    'type' => 'posts', 
    'size' => 25, 
    'from' => 0, 
    'body' => [ 
     'sort' => [ 
      '_geo_distance' => [ 
       'post_location' => [ 
        'lat' => '44.4759', 
        'lon' => '-73.2121' 
       ], 
       'order' => 'asc', 
       'unit' => 'mi' 
      ] 
     ], 
     'query' => [ 
      'filtered' => [ 
       'query' => [ 
        'match_all' => [] 
       ], 
       'filter' => [ 
        'geo_shape' => [ 
         'reach' => [ 
          'relation' => 'INTERSECTS', 
          'shape' => [ 
           'type' => 'circle', 
           'coordinates' => [-73.2121, 44.4759], 
           'radius' => '20mi' 
          ] 
         ] 
        ] 
       ] 
      ] 
     ] 
    ] 
]; 
+0

В вашем примере фактический запрос будет использовать пользователи lat/lon, а не post lat/lon, это правильно? Я дам этот пример выстрелу немного, и если он сработает, я приму свой ответ. –

+0

Да, в запросе вы используете пользовательский лат/лон, который будет сопоставлен с формой, сосредоточенной на лате/lon каждого сообщения. – Val

+0

. Оглядываясь на это, я не уверен, что это будет работать или нет, но я еще не попытался это сделать. Однако Местный, возможно, ограничен 20 милями, но Региональный будет ограничен 200 милями, затем Национальным и Мировым. У мира, очевидно, не было бы предела, но мне нужно было бы отфильтровать пределы для локального, национального, регионального, а не только одного предела расстояния ... –

Смежные вопросы