Запрос по гео-форме

Вы можете фильтровать документы, используя гео-форму, определенную в запросе, или использовать заранее индексированную гео-форму.

Используйте запрос по гео-форме для поиска документов, которые содержат поля geopoint или geoshape. Вы можете фильтровать документы, используя гео-форму, определенную в запросе, или использовать заранее индексированную гео-форму.

Иск searched document field must be mapped as geo_point или geo_shape.

Пространственные отношения

Когда вы предоставляете гео-форму для запроса по гео-форме, поля geopoint и geoshape в документах сопоставляются с использованием следующих пространственных отношений к предоставленной форме:

Отношение Описание Поддерживаемый тип географического поля
INTERSECTS (По умолчанию) Соответствует документам, чьи geopoint или geoshape пересекаются с формой, предоставленной в запросе. geo_point, geo_shape
DISJOINT Соответствует документам, чьи geoshape не пересекаются с формой, предоставленной в запросе. geo_shape
WITHIN Соответствует документам, чьи geoshape полностью находятся внутри формы, предоставленной в запросе. geo_shape
CONTAINS Соответствует документам, чьи geoshape полностью содержат форму, предоставленную в запросе. geo_shape

Определение формы в запросе по гео-форме

Вы можете определить форму для фильтрации документов в запросе по гео-форме, предоставив новое определение формы во время запроса или сославшись на имя формы, заранее индексированной в другом индексе.

Использование нового определения формы

Чтобы предоставить новую форму для запроса по гео-форме, определите ее в поле geo_shape. Вы должны определить гео-форму в формате GeoJSON.

Следующий пример иллюстрирует поиск документов, содержащих гео-формы, которые соответствуют гео-форме, определенной во время запроса.

Шаг 1: Создание индекса

Сначала создайте индекс и сопоставьте поле location как geo_shape:

PUT /testindex
{
  "mappings": {
    "properties": {
      "location": {
        "type": "geo_shape"
      }
    }
  }
}

Шаг 2: Индексация документов

Индексуйте один документ, содержащий точку, и другой, содержащий многоугольник:

PUT testindex/_doc/1
{
  "location": {
    "type": "point",
    "coordinates": [ 73.0515, 41.5582 ]
  }
}

PUT testindex/_doc/2
{
  "location": {
    "type": "polygon",
    "coordinates": [
      [
        [
          73.0515,
          41.5582
        ],
        [
          72.6506,
          41.5623
        ],
        [
          72.6734,
          41.7658
        ],
        [
          73.0515,
          41.5582
        ]
      ]
    ]
  }
}

Шаг 3: Выполнение запроса по гео-форме

Наконец, определите гео-форму для фильтрации документов. Следующие разделы иллюстрируют предоставление различных гео-форм в запросе. Для получения дополнительной информации о различных форматах гео-форм см. раздел “Тип поля гео-формы”.

Конверт

Конверт — это ограничивающий прямоугольник в формате [[minLon, maxLat], [maxLon, minLat]]. Ищите документы, содержащие поля geoshape, которые пересекаются с предоставленным конвертом:

GET /testindex/_search
{
  "query": {
    "geo_shape": {
      "location": {
        "shape": {
          "type": "envelope",
          "coordinates": [
            [
              71.0589,
              42.3601
            ],
            [
              74.006,
              40.7128
            ]
          ]
        },
        "relation": "WITHIN"
      }
    }
  }
}

Ответ содержит оба документа:

{
  "took": 5,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 0,
    "hits": [
      {
        "_index": "testindex",
        "_id": "1",
        "_score": 0,
        "_source": {
          "location": {
            "type": "point",
            "coordinates": [
              73.0515,
              41.5582
            ]
          }
        }
      },
      {
        "_index": "testindex",
        "_id": "2",
        "_score": 0,
        "_source": {
          "location": {
            "type": "polygon",
            "coordinates": [
              [
                [
                  73.0515,
                  41.5582
                ],
                [
                  72.6506,
                  41.5623
                ],
                [
                  72.6734,
                  41.7658
                ],
                [
                  73.0515,
                  41.5582
                ]
              ]
            ]
          }
        }
      }
    ]
  }
}

Точка

Ищите документы, чьи поля geoshape содержат предоставленную точку:

GET /testindex/_search
{
  "query": {
    "geo_shape": {
      "location": {
        "shape": {
          "type": "point",
          "coordinates": [
            72.8000, 
            41.6300
          ]
        },
        "relation": "CONTAINS"
      }
    }
  }
}

Linestring

Поиск документов, геошейпы которых не пересекаются с предоставленным линией:

GET /testindex/_search
{
  "query": {
    "geo_shape": {
      "location": {
        "shape": {
          "type": "linestring",
          "coordinates": [[74.0060, 40.7128], [71.0589, 42.3601]]
        },
        "relation": "DISJOINT"
      }
    }
  }
}

Запросы геошейпа с линией не поддерживают отношение WITHIN.

Полигон

В формате GeoJSON необходимо перечислить вершины полигона в порядке обхода против часовой стрелки и замкнуть полигон, чтобы первая и последняя вершины совпадали.

Поиск документов, геошейпы которых находятся внутри предоставленного полигона:

GET /testindex/_search
{
  "query": {
    "geo_shape": {
      "location": {
        "shape": {
          "type": "polygon",
          "coordinates": [
            [
              [74.0060, 40.7128], 
              [73.7562, 42.6526], 
              [71.0589, 42.3601], 
              [74.0060, 40.7128]
            ]
          ]
        },
        "relation": "WITHIN"
      }
    }
  }
}

Мультипоинт

Поиск документов, геошейпы которых не пересекаются с предоставленными точками:

GET /testindex/_search
{
  "query": {
    "geo_shape": {
      "location": {
        "shape": {
          "type": "multipoint",
          "coordinates": [
            [74.0060, 40.7128], 
            [71.0589, 42.3601]
          ]
        },
        "relation": "DISJOINT"
      }
    }
  }
}

Мультилиния

Поиск документов, геошейпы которых не пересекаются с предоставленными линиями:

GET /testindex/_search
{
  "query": {
    "geo_shape": {
      "location": {
        "shape": {
          "type": "multilinestring",
          "coordinates": [
            [[74.0060, 40.7128], [71.0589, 42.3601]],
            [[73.7562, 42.6526], [72.6734, 41.7658]]
          ]
        },
        "relation": "disjoint"
      }
    }
  }
}

Запросы геошейпа с мультилинией не поддерживают отношение WITHIN.

Мультиполигоны

Поиск документов, геошейпы которых находятся внутри предоставленного мультиполигона:

GET /testindex/_search
{
  "query": {
    "geo_shape": {
      "location": {
        "shape": {
          "type": "multipolygon",
          "coordinates": [
            [
              [
                [74.0060, 40.7128], 
                [73.7562, 42.6526], 
                [71.0589, 42.3601], 
                [74.0060, 40.7128]
              ],
              [
                [73.0515, 41.5582], 
                [72.6506, 41.5623], 
                [72.6734, 41.7658], 
                [73.0515, 41.5582]
              ]
            ],
            [
              [
                [73.9146, 40.8252], 
                [73.8871, 41.0389], 
                [73.6853, 40.9747], 
                [73.9146, 40.8252]
              ]
            ]
          ]
        },
        "relation": "WITHIN"
      }
    }
  }
}

Коллекция геометрий

Поиск документов, геошейпы которых находятся внутри предоставленных полигонов:

GET /testindex/_search
{
  "query": {
    "geo_shape": {
      "location": {
        "shape": {
          "type": "geometrycollection",
          "geometries": [
            {
              "type": "polygon",
              "coordinates": [[
                [74.0060, 40.7128], 
                [73.7562, 42.6526], 
                [71.0589, 42.3601], 
                [74.0060, 40.7128]
              ]]
            },
            {
              "type": "polygon",
              "coordinates": [[
                [73.0515, 41.5582], 
                [72.6506, 41.5623], 
                [72.6734, 41.7658], 
                [73.0515, 41.5582]
              ]]
            }
          ]
        },
        "relation": "WITHIN"
      }
    }
  }
}

Запросы геошейпа, содержащие в коллекции геометрий линию или мультилинии, не поддерживают отношение WITHIN.

Использование прединдексированного определения формы

При построении запроса геошейпа вы также можете ссылаться на имя формы, прединдексированной в другом индексе. С помощью этого метода вы можете определить геошейп во время индексации и ссылаться на него по имени во время поиска.

Вы можете определить прединдексированный геошейп в формате GeoJSON или Well-Known Text (WKT). Для получения дополнительной информации о различных форматах геошейпа см. тип поля Geoshape.

Объект indexed_shape поддерживает следующие параметры:

Параметр Обязательный/Необязательный Описание
id Обязательный Идентификатор документа, содержащего прединдексированную форму.
index Необязательный Имя индекса, содержащего прединдексированную форму. По умолчанию - shapes.
path Необязательный Имя поля, содержащего прединдексированную форму в виде пути. По умолчанию - shape.
routing Необязательный Маршрутизация документа, содержащего прединдексированную форму.

Следующий пример иллюстрирует, как ссылаться на имя формы, прединдексированной в другом индексе. В этом примере индекс pre-indexed-shapes содержит форму, определяющую границы, а индекс testindex содержит формы, которые проверяются на соответствие этим границам.

Сначала создайте индекс pre-indexed-shapes и задайте поле boundaries для этого индекса как geo_shape:

PUT /pre-indexed-shapes
{
  "mappings": {
    "properties": {
      "boundaries": {
        "type": "geo_shape",
        "orientation": "left"
      }
    }
  }
}

Для получения дополнительной информации о том, как задать другую ориентацию вершин для полигонов, см. Полигон.

Индексируйте полигон, указывая границы поиска, в индекс pre-indexed-shapes. Идентификатор полигона - search_triangle. В этом примере вы индексируете полигон в формате WKT:

PUT /pre-indexed-shapes/_doc/search_triangle
{
  "boundaries": 
    "POLYGON ((74.0060 40.7128, 71.0589 42.3601, 73.7562 42.6526, 74.0060 40.7128))"
}

Если вы еще не сделали этого, индексируйте один документ, содержащий точку, и другой документ, содержащий полигон, в индекс testindex:

PUT /testindex/_doc/1
{
  "location": {
    "type": "point",
    "coordinates": [ 73.0515, 41.5582 ]
  }
}
PUT /testindex/_doc/2
{
  "location": {
    "type": "polygon",
    "coordinates": [
      [
        [
          73.0515,
          41.5582
        ],
        [
          72.6506,
          41.5623
        ],
        [
          72.6734,
          41.7658
        ],
        [
          73.0515,
          41.5582
        ]
      ]
    ]
  }
}

Поиск документов, геошейпы которых находятся внутри search_triangle:

GET /testindex/_search
{
  "query": {
    "bool": {
      "must": {
        "match_all": {}
      },
      "filter": {
        "geo_shape": {
          "location": {
            "indexed_shape": {
              "index": "pre-indexed-shapes",
              "id": "search_triangle",
              "path": "boundaries"
            },
            "relation": "WITHIN"
          }
        }
      }
    }
  }
}

Ответ содержит оба документа.

Запрос геоточек

Вы также можете использовать запрос геошейпа для поиска документов, содержащих геоточки.

Запросы геошейпа по полям геоточек поддерживают только пространственное отношение по умолчанию INTERSECTS, поэтому вам не нужно указывать параметр отношения.

Запросы геошейпа по полям геоточек не поддерживают следующие геошейпы:

  • Точки
  • Линии
  • Мультипоинты
  • Мультилинии
  • Коллекции геометрий, содержащие один из вышеперечисленных типов геошейпа

Создайте отображение, где location является geo_point:

PUT /testindex1
{
  "mappings": {
    "properties": {
      "location": {
        "type": "geo_point"
      }
    }
  }
}

Индексируйте две точки в индекс. В этом примере вы предоставите координаты геоточек в виде строк:

PUT /testindex1/_doc/1
{
  "location": "41.5623, 72.6506"
}
PUT /testindex1/_doc/2
{
  "location": "76.0254, 39.2467" 
}

Для получения информации о предоставлении координат геоточек в различных форматах см. Форматы.

Поиск геоточек, которые пересекаются с предоставленным полигоном:

GET /testindex1/_search
{
  "query": {
    "geo_shape": {
      "location": {
        "shape": {
          "type": "polygon",
          "coordinates": [
            [
              [74.0060, 40.7128], 
              [73.7562, 42.6526], 
              [71.0589, 42.3601], 
              [74.0060, 40.7128]
            ]
          ]
        }
      }
    }
  }
}

Ответ на запрос

Ответ возвращает документ 1:

{
  "took": 21,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0,
    "hits": [
      {
        "_index": "testindex1",
        "_id": "1",
        "_score": 0,
        "_source": {
          "location": "41.5623, 72.6506"
        }
      }
    ]
  }
}

Обратите внимание, что при индексации геоточек вы указали их координаты в формате “широта, долгота”. Когда вы ищете соответствующие документы, массив координат находится в формате [долгота, широта]. Таким образом, документ 1 возвращается в результатах, но документ 2 - нет.

Параметры

Запросы геошейпа принимают следующие параметры:

Параметр Тип данных Описание
ignore_unmapped Boolean Указывает, следует ли игнорировать неразмеченное поле. Если установлено в true, то запрос не возвращает документы, содержащие неразмеченное поле. Если установлено в false, то при отсутствии поля выбрасывается исключение. Необязательный. По умолчанию - false.