Агрегирование по сетке геогекса
Мульти-категориальная агрегация, которая группирует значения geo_point и geo_shape в категории, представляющие сетку. Результирующая сетка может быть разреженной и содержит только ячейки с соответствующими данными. Каждая ячейка соответствует индексу ячейки H3 и маркируется с использованием представления H3Index.
См. таблицу площадей ячеек для разрешений H3, чтобы узнать, как точность (зум) коррелирует с размером на местности. Точность для этой агрегации может быть от 0 до 15 включительно.
Запросы с высокой точностью могут быть очень дорогими в плане использования ОЗУ и размера результатов. Например, самый высокоточный geohex с точностью 15 создаёт ячейки, которые покрывают менее одного квадратного метра. Мы рекомендуем использовать фильтр для ограничения запросов высокой точности на меньшей географической области. Пример см. в Запросах высокой точности.
Простой запрос с низкой точностью
resp = client.indices.create(
index="museums",
mappings={
"properties": {
"location": {
"type": "geo_point"
}
}
},
)
print(resp)
resp1 = client.bulk(
index="museums",
refresh=True,
operations=[
{
"index": {
"_id": 1
}
},
{
"location": "POINT (4.912350 52.374081)",
"name": "NEMO Science Museum"
},
{
"index": {
"_id": 2
}
},
{
"location": "POINT (4.901618 52.369219)",
"name": "Museum Het Rembrandthuis"
},
{
"index": {
"_id": 3
}
},
{
"location": "POINT (4.914722 52.371667)",
"name": "Nederlands Scheepvaartmuseum"
},
{
"index": {
"_id": 4
}
},
{
"location": "POINT (4.405200 51.222900)",
"name": "Letterenhuis"
},
{
"index": {
"_id": 5
}
},
{
"location": "POINT (2.336389 48.861111)",
"name": "Musée du Louvre"
},
{
"index": {
"_id": 6
}
},
{
"location": "POINT (2.327000 48.860000)",
"name": "Musée d'Orsay"
}
],
)
print(resp1)
resp2 = client.search(
index="museums",
size="0",
aggregations={
"large-grid": {
"geohex_grid": {
"field": "location",
"precision": 4
}
}
},
)
print(resp2) response = client.indices.create(
index: 'museums',
body: {
mappings: {
properties: {
location: {
type: 'geo_point'
}
}
}
}
)
puts response
response = client.bulk(
index: 'museums',
refresh: true,
body: [
{
index: {
_id: 1
}
},
{
location: 'POINT (4.912350 52.374081)',
name: 'NEMO Science Museum'
},
{
index: {
_id: 2
}
},
{
location: 'POINT (4.901618 52.369219)',
name: 'Museum Het Rembrandthuis'
},
{
index: {
_id: 3
}
},
{
location: 'POINT (4.914722 52.371667)',
name: 'Nederlands Scheepvaartmuseum'
},
{
index: {
_id: 4
}
},
{
location: 'POINT (4.405200 51.222900)',
name: 'Letterenhuis'
},
{
index: {
_id: 5
}
},
{
location: 'POINT (2.336389 48.861111)',
name: 'Musée du Louvre'
},
{
index: {
_id: 6
}
},
{
location: 'POINT (2.327000 48.860000)',
name: "Musée d'Orsay"
}
]
)
puts response
response = client.search(
index: 'museums',
size: 0,
body: {
aggregations: {
"large-grid": {
geohex_grid: {
field: 'location',
precision: 4
}
}
}
}
)
puts response const response = await client.indices.create({
index: "museums",
mappings: {
properties: {
location: {
type: "geo_point",
},
},
},
});
console.log(response);
const response1 = await client.bulk({
index: "museums",
refresh: "true",
operations: [
{
index: {
_id: 1,
},
},
{
location: "POINT (4.912350 52.374081)",
name: "NEMO Science Museum",
},
{
index: {
_id: 2,
},
},
{
location: "POINT (4.901618 52.369219)",
name: "Museum Het Rembrandthuis",
},
{
index: {
_id: 3,
},
},
{
location: "POINT (4.914722 52.371667)",
name: "Nederlands Scheepvaartmuseum",
},
{
index: {
_id: 4,
},
},
{
location: "POINT (4.405200 51.222900)",
name: "Letterenhuis",
},
{
index: {
_id: 5,
},
},
{
location: "POINT (2.336389 48.861111)",
name: "Musée du Louvre",
},
{
index: {
_id: 6,
},
},
{
location: "POINT (2.327000 48.860000)",
name: "Musée d'Orsay",
},
],
});
console.log(response1);
const response2 = await client.search({
index: "museums",
size: 0,
aggregations: {
"large-grid": {
geohex_grid: {
field: "location",
precision: 4,
},
},
},
});
console.log(response2); PUT /museums
{
"mappings": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}
POST /museums/_bulk?refresh
{"index":{"_id":1}}
{"location": "POINT (4.912350 52.374081)", "name": "NEMO Science Museum"}
{"index":{"_id":2}}
{"location": "POINT (4.901618 52.369219)", "name": "Museum Het Rembrandthuis"}
{"index":{"_id":3}}
{"location": "POINT (4.914722 52.371667)", "name": "Nederlands Scheepvaartmuseum"}
{"index":{"_id":4}}
{"location": "POINT (4.405200 51.222900)", "name": "Letterenhuis"}
{"index":{"_id":5}}
{"location": "POINT (2.336389 48.861111)", "name": "Musée du Louvre"}
{"index":{"_id":6}}
{"location": "POINT (2.327000 48.860000)", "name": "Musée d'Orsay"}
POST /museums/_search?size=0
{
"aggregations": {
"large-grid": {
"geohex_grid": {
"field": "location",
"precision": 4
}
}
}
} Ответ:
{
...
"aggregations": {
"large-grid": {
"buckets": [
{
"key": "841969dffffffff",
"doc_count": 3
},
{
"key": "841fb47ffffffff",
"doc_count": 2
},
{
"key": "841fa4dffffffff",
"doc_count": 1
}
]
}
}
} Запросы высокой точности
При запросе детальных категорий (обычно для отображения карты с «приближением») следует применять фильтр, такой как geo_bounding_box, чтобы сузить область. В противном случае могут быть созданы и возвращены потенциально миллионы категорий.
resp = client.search(
index="museums",
size="0",
aggregations={
"zoomed-in": {
"filter": {
"geo_bounding_box": {
"location": {
"top_left": "POINT (4.9 52.4)",
"bottom_right": "POINT (5.0 52.3)"
}
}
},
"aggregations": {
"zoom1": {
"geohex_grid": {
"field": "location",
"precision": 12
}
}
}
}
},
)
print(resp) const response = await client.search({
index: "museums",
size: 0,
aggregations: {
"zoomed-in": {
filter: {
geo_bounding_box: {
location: {
top_left: "POINT (4.9 52.4)",
bottom_right: "POINT (5.0 52.3)",
},
},
},
aggregations: {
zoom1: {
geohex_grid: {
field: "location",
precision: 12,
},
},
},
},
},
});
console.log(response); POST /museums/_search?size=0
{
"aggregations": {
"zoomed-in": {
"filter": {
"geo_bounding_box": {
"location": {
"top_left": "POINT (4.9 52.4)",
"bottom_right": "POINT (5.0 52.3)"
}
}
},
"aggregations": {
"zoom1": {
"geohex_grid": {
"field": "location",
"precision": 12
}
}
}
}
}
} Ответ:
{
...
"aggregations": {
"zoomed-in": {
"doc_count": 3,
"zoom1": {
"buckets": [
{
"key": "8c1969c9b2617ff",
"doc_count": 1
},
{
"key": "8c1969526d753ff",
"doc_count": 1
},
{
"key": "8c1969526d26dff",
"doc_count": 1
}
]
}
}
}
} Запросы с дополнительным фильтрованием по прямоугольнику
Агрегирование geohex_grid поддерживает необязательный параметр bounds, который ограничивает рассматриваемые ячейки теми, которые пересекают заданные границы. Параметр bounds принимает те же форматы прямоугольников, что и запрос гео-прямоугольника. Этот прямоугольник может использоваться с или без дополнительного запроса geo_bounding_box для фильтрации точек до агрегирования. Это независимый прямоугольник, который может пересекаться с, быть равен или не пересекаться с любыми дополнительными запросами geo_bounding_box, определёнными в контексте агрегации.
resp = client.search(
index="museums",
size="0",
aggregations={
"tiles-in-bounds": {
"geohex_grid": {
"field": "location",
"precision": 12,
"bounds": {
"top_left": "POINT (4.9 52.4)",
"bottom_right": "POINT (5.0 52.3)"
}
}
}
},
)
print(resp) const response = await client.search({
index: "museums",
size: 0,
aggregations: {
"tiles-in-bounds": {
geohex_grid: {
field: "location",
precision: 12,
bounds: {
top_left: "POINT (4.9 52.4)",
bottom_right: "POINT (5.0 52.3)",
},
},
},
},
});
console.log(response); POST /museums/_search?size=0
{
"aggregations": {
"tiles-in-bounds": {
"geohex_grid": {
"field": "location",
"precision": 12,
"bounds": {
"top_left": "POINT (4.9 52.4)",
"bottom_right": "POINT (5.0 52.3)"
}
}
}
}
} Ответ:
{
...
"aggregations": {
"tiles-in-bounds": {
"buckets": [
{
"key": "8c1969c9b2617ff",
"doc_count": 1
},
{
"key": "8c1969526d753ff",
"doc_count": 1
},
{
"key": "8c1969526d26dff",
"doc_count": 1
}
]
}
}
} Агрегирование полей geo_shape
Агрегирование по полям Geoshape работает почти так же, как и для точек. Есть два ключевых отличия:
- При агрегировании по данным
geo_point, точки считаются внутри шестиугольной плитки, если они лежат внутри границ, определённых большими кругами. Другими словами, вычисление выполняется в сферических координатах. Однако при агрегировании по даннымgeo_shape, фигуры считаются внутри шестиугольника, если они лежат внутри границ, определённых как прямые линии на равнопрямоугольной проекции. Причина в том, что Elasticsearch и Lucene обрабатывают границы, используя равнопрямоугольную проекцию во время индексации и поиска. Чтобы обеспечить соответствие результатов поиска и результатов агрегации, мы также используем равнопрямоугольную проекцию в агрегациях. Для большинства данных разница незначительна или незаметна. Однако для низких уровней масштаба (низкой точности), особенно далеко от экватора, это может быть заметно. Например, если одни и те же данные о точке индексируются какgeo_pointиgeo_shape, возможно получение разных результатов при агрегировании на более низких разрешениях. - Как и в случае с
geotile_grid, одна фигура может быть учтена в нескольких плитках. Фигура будет учитываться в подсчёте совпадающих значений, если любая часть её фигуры пересекается с этой плиткой. Ниже приведена иллюстрация этого:
Параметры
| field | (Обязательно, строка) Поле, содержащее индексированные значения geo-точки или geo-фигуры. Должно быть явно отображено как |
| precision | (Необязательно, целое число) Целочисленный зум ключа, используемого для определения ячеек/категорий в результатах. По умолчанию |
| bounds | (Необязательно, объект) Область, используемая для фильтрации гео-точек или гео-фигур в каждой категории. Принимает те же форматы прямоугольников, что и запрос гео-прямоугольника. |
| size | (Необязательно, целое число) Максимальное количество категорий для возврата. По умолчанию 10 000. При усечении результатов категории имеют приоритет, исходя из объёма документов, которые они содержат. |
| shard_size | (Необязательно, целое число) Количество категорий, возвращаемых с каждого фрагмента. По умолчанию |
© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/8.17/search-aggregations-bucket-geohexgrid-aggregation.html