# Сложный поисковый запрос

**URL:** <https://discuss.elastic.co/t/topic/143137>\
**Category:** Вопросы на русском языке\
**Created:** [August 6, 2018, 10:05am UTC](https://discuss.elastic.co/t/topic/143137 "2018-08-06T10:05:35Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![111126](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/111126/32/36818_2.png) [@111126](https://discuss.elastic.co/u/111126)\
**Post date:** [August 6, 2018, 10:05am UTC](https://discuss.elastic.co/t/topic/143137/1 "2018-08-06T10:05:35Z")

</div>

Нужна помощь по составлению сложного запроса.  
Основа запроса вот такая [https://www.elastic.co/guide/en/elasticsearch/reference/6.1/query-dsl-geo-distance-query.html#\_lat\_lon\_as\_properties\_3](https://www.elastic.co/guide/en/elasticsearch/reference/6.1/query-dsl-geo-distance-query.html#_lat_lon_as_properties_3)  
Но вот эту часть:  
"pin.location" : {  
"lat" : 40,  
"lon" : -70  
}  
надо усложнить. У меня есть индекс который содержит в себе много документов с координатами. Соответственно мне надо перебрать из одного индекса все координаты в документах где поле id=345wq и и поискать в определенном радиусе соответствующие документы в другом индексе

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [August 6, 2018, 3:13pm UTC](https://discuss.elastic.co/t/topic/143137/2 "2018-08-06T15:13:12Z")

</div>

> где поле id=345wq

это будет [term query](https://www.elastic.co/guide/en/elasticsearch/reference/6.1/query-dsl-term-query.html)

> и поискать в определенном радиусе соответствующие документы в другом индексе

а для этого, вам придется собрать все эти координаты вручную и искать другим запросом в другом индексе. Elasticsearch операции JOIN между индексами пока не поддерживает. Только в одном индексе и только в отношении "Один ко многим".

---

<div class="post-metadata">

**Author:** ![111126](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/111126/32/36818_2.png) [@111126](https://discuss.elastic.co/u/111126)\
**Post date:** [August 6, 2018, 3:17pm UTC](https://discuss.elastic.co/t/topic/143137/3 "2018-08-06T15:17:47Z")

</div>

> [@Igor\_Motov](#):
>
> а для этого, вам придется собрать все эти координаты вручную и искать другим запросом в другом индексе.

Честно сказать не понял механику. Если можно покажите на примере. Заранее спасибо!

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [August 6, 2018, 3:36pm UTC](https://discuss.elastic.co/t/topic/143137/4 "2018-08-06T15:36:18Z")

</div>

Ну, скажем, вот мой первый индекс:

```auto
PUT test
{
  "mappings": {
    "doc": {
      "properties": {
        "id": {
          "type": "keyword"
        },
        "loc": {
          "type": "geo_point"
        }
      }
    }
  }  
}

PUT test/doc/1
{
  "id": "foo",
  "loc": "42.358056,-71.063611"
}

PUT test/doc/2
{
  "id": "foo",
  "loc": "55.75,37.616667"
}

PUT test/doc/3
{
  "id": "bar",
  "loc":"40.7127,-74.0059"
}

```

Я сначала нахожу нужные координаты:

```auto
GET test/doc/_search
{
  "query": {
    "term": {
      "id": {
        "value": "foo"
      }
    }
  }
}

```

Этот запрос возвращает мне `"42.358056,-71.063611"` и `"55.75,37.616667"`. Я из них в моем приложении формирую следующей запрос:

```auto
GET other_index/doc/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "geo_distance": {
            "distance": "12km",
            "loc": "42.358056,-71.063611"
          }
        },
        {
          "geo_distance": {
            "distance": "12km",
            "loc": "55.75,37.616667"
          }
        }
      ]
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![111126](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/111126/32/36818_2.png) [@111126](https://discuss.elastic.co/u/111126)\
**Post date:** [August 7, 2018, 7:20am UTC](https://discuss.elastic.co/t/topic/143137/5 "2018-08-07T07:20:58Z")

</div>

Но в моем первом индексе там очень много документов (подвижное устройство постоянно отсылающее свои координаты), не ужели и правда вручную прогонять поштучно запросы для всего дневного маршрута моего устройства, чтобы понять какие статичные точки (магазины и т.д.) попадались в течении дня в радиусе 300 метров на маршруте?  
Может как-то надо по другому данные сложить, чтобы более эффективно решить мою задачу?

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [August 7, 2018, 1:38pm UTC](https://discuss.elastic.co/t/topic/143137/6 "2018-08-07T13:38:15Z")

</div>

Может тогда из маршрута сделать geo\_shape и искать пересечения?

---

<div class="post-metadata">

**Author:** ![111126](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/111126/32/36818_2.png) [@111126](https://discuss.elastic.co/u/111126)\
**Post date:** [August 8, 2018, 9:01am UTC](https://discuss.elastic.co/t/topic/143137/7 "2018-08-08T09:01:12Z")

</div>

> [@Igor\_Motov](#):
>
> Может тогда из маршрута сделать geo\_shape и искать пересечения?

Ознакомился, теоритически подходит. Собираю из точек передвижения моего устройства так называемый LineString и дальше смотрю какие статичные точки (магазины) попали в рамки моего LineString.  
Но с практической точки зрения как это выглядит не ясно. получается мне надо формировать LineString в какой-то отдельный индекс что-ли? Как формируется LineString, придеться все координаты передаваемые устройством писать в один документ чтобы они собирали в geo shape ? А как Тогда производить фильтрацию, например по дате?

Игорь, если вас не затруднит , можете пример дать из которого можно будет понять как фактически это работает? Спасибо.

---

<div class="post-metadata">

**Author:** ![111126](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/111126/32/36818_2.png) [@111126](https://discuss.elastic.co/u/111126)\
**Post date:** [August 8, 2018, 1:38pm UTC](https://discuss.elastic.co/t/topic/143137/8 "2018-08-08T13:38:27Z")

</div>

получается примерно вот таким запросом я могу поискать свои статические точки (магазины) встречающиеся на пути [[-77.03653, 38.897676], [-77.009051, 38.889939]]

> curl -XGET '[http://localhost:9200/anyindex/anytype/\_search?pretty](http://localhost:9200/anyindex/anytype/_search?pretty)' -d '{  
> "query": {  
> "filtered": {  
> "filter": {  
> "geo\_shape": {  
> "location": {  
> "relation": "intersects",  
> "shape": {  
> "type": "linestring",  
> "coordinates":[[-77.03653, 38.897676], [-77.009051, 38.889939]]  
> }  
> }  
> }  
> },  
> "query": {  
> "match\_all": {}  
> }  
> }  
> }  
> }'

Но как мне из моих документов с координатами приходящими от gps устройства получить тот самый geo shape для подстановки в запрос выше мне не понятно. Да и не ясно что значит intersects, по документации говорится что найдутся точки пересекающиеся с маршрутом, но с какой точность (в каком радиусе) пересечение будет защитано ?

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [August 8, 2018, 2:37pm UTC](https://discuss.elastic.co/t/topic/143137/9 "2018-08-08T14:37:23Z")

</div>

> Да и не ясно что значит intersects, по документации говорится что найдутся точки пересекающиеся с маршрутом, но с какой точность (в каком радиусе) пересечение будет защитано ?

Вы можете сделать из multiline mutltipoligon с желаемым радиусом.

---

<div class="post-metadata">

**Author:** ![111126](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/111126/32/36818_2.png) [@111126](https://discuss.elastic.co/u/111126)\
**Post date:** [August 8, 2018, 2:39pm UTC](https://discuss.elastic.co/t/topic/143137/10 "2018-08-08T14:39:36Z")

</div>

> [@Igor\_Motov](#):
>
> Вы можете сделать из multiline mutltipoligon с желаемым радиусом.

А как быть с этим:

> Но как мне из моих документов с координатами приходящими от gps устройства получить тот самый geo shape

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [August 8, 2018, 2:55pm UTC](https://discuss.elastic.co/t/topic/143137/11 "2018-08-08T14:55:35Z")

</div>

> Но как мне из моих документов с координатами приходящими от gps устройства получить тот самый geo shape

Если особой точности не нужно, то можно поиграться уменьшением `precision`. Но при этом совпадения могут быть очень непредсказуемы (по сути все будет зависеть попала линия и магазин в одну клетку). Если нужно более-менее точное и предсказуемое поведение, то Elasticsearch вам тут не поможет. Я бы начал с изучения [java - Computing a polygon that surrounds a multi-point line - Stack Overflow](https://stackoverflow.com/questions/5771908/computing-a-polygon-that-surrounds-a-multi-point-line)

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [September 5, 2018, 2:55pm UTC](https://discuss.elastic.co/t/topic/143137/12 "2018-09-05T14:55:39Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
