Spec-Zone.ru › Elasticsearch 7
›Elasticsearch Guide [7.17] ›Агрегирование ›Агрегирование по корзинам

Агрегация по расстоянию

Многокорзинная агрегация, которая работает с полями geo_point и концептуально очень похожа на агрегацию диапазона. Пользователь может определить точку начала отсчёта и набор корзин с диапазонами расстояний. Агрегация вычисляет расстояние каждого значения документа от точки начала отсчёта и определяет корзину, в которую оно попадает, на основе диапазонов (документ попадает в корзину, если расстояние между документом и точкой начала отсчёта попадает в диапазон расстояний корзины).

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

POST /museums/_bulk?refresh
{"index":{"_id":1}}
{"location": "52.374081,4.912350", "name": "NEMO Science Museum"}
{"index":{"_id":2}}
{"location": "52.369219,4.901618", "name": "Museum Het Rembrandthuis"}
{"index":{"_id":3}}
{"location": "52.371667,4.914722", "name": "Nederlands Scheepvaartmuseum"}
{"index":{"_id":4}}
{"location": "51.222900,4.405200", "name": "Letterenhuis"}
{"index":{"_id":5}}
{"location": "48.861111,2.336389", "name": "Musée du Louvre"}
{"index":{"_id":6}}
{"location": "48.860000,2.327000", "name": "Musée d'Orsay"}

POST /museums/_search?size=0
{
  "aggs": {
    "rings_around_amsterdam": {
      "geo_distance": {
        "field": "location",
        "origin": "52.3760, 4.894",
        "ranges": [
          { "to": 100000 },
          { "from": 100000, "to": 300000 },
          { "from": 300000 }
        ]
      }
    }
  }
}

Ответ:

{
  ...
  "aggregations": {
    "rings_around_amsterdam": {
      "buckets": [
        {
          "key": "*-100000.0",
          "from": 0.0,
          "to": 100000.0,
          "doc_count": 3
        },
        {
          "key": "100000.0-300000.0",
          "from": 100000.0,
          "to": 300000.0,
          "doc_count": 1
        },
        {
          "key": "300000.0-*",
          "from": 300000.0,
          "doc_count": 2
        }
      ]
    }
  }
}

Указанное поле должно быть типа geo_point (который может быть установлен только явно в отображениях). Также оно может содержать массив полей типа geo_point, в этом случае все поля будут учтены при агрегации. Точка начала отсчёта может принимать все форматы, поддерживаемые типом geo_point:

  • Формат объекта: { "lat" : 52.3760, "lon" : 4.894 } — это наиболее безопасный формат, поскольку он наиболее чётко определяет значения lat и lon
  • Формат строки: "52.3760, 4.894" — где первое число — это lat, а второе — это lon
  • Формат массива: [4.894, 52.3760] — основанный на стандарте GeoJSON, где первое число — это lon, а второе — это lat

По умолчанию единицей измерения расстояния является m (метры), но также можно использовать: mi (мили), in (дюймы), yd (ярды), km (километры), cm (сантиметры), mm (миллиметры).

POST /museums/_search?size=0
{
  "aggs": {
    "rings": {
      "geo_distance": {
        "field": "location",
        "origin": "52.3760, 4.894",
        "unit": "km", 
        "ranges": [
          { "to": 100 },
          { "from": 100, "to": 300 },
          { "from": 300 }
        ]
      }
    }
  }
}

Расстояния будут вычисляться в километрах

Существует два режима вычисления расстояния: arc (по умолчанию) и plane. Расчёт с помощью arc наиболее точный. Расчёт с помощью plane самый быстрый, но наименее точный. Рассмотрите использование plane, когда область поиска «узкая» и охватывает меньшие географические области (~5 км). plane вернёт более высокие погрешности при поиске в очень больших областях (например, поиск через континенты). Тип вычисления расстояния можно задать параметром distance_type:

POST /museums/_search?size=0
{
  "aggs": {
    "rings": {
      "geo_distance": {
        "field": "location",
        "origin": "52.3760, 4.894",
        "unit": "km",
        "distance_type": "plane",
        "ranges": [
          { "to": 100 },
          { "from": 100, "to": 300 },
          { "from": 300 }
        ]
      }
    }
  }
}

Ключевой ответ

Установив флаг keyed в значение true, вы назначите уникальный строковый ключ каждой корзине и вернёте диапазоны в виде хэша, а не массива:

POST /museums/_search?size=0
{
  "aggs": {
    "rings_around_amsterdam": {
      "geo_distance": {
        "field": "location",
        "origin": "52.3760, 4.894",
        "ranges": [
          { "to": 100000 },
          { "from": 100000, "to": 300000 },
          { "from": 300000 }
        ],
        "keyed": true
      }
    }
  }
}

Ответ:

{
  ...
  "aggregations": {
    "rings_around_amsterdam": {
      "buckets": {
        "*-100000.0": {
          "from": 0.0,
          "to": 100000.0,
          "doc_count": 3
        },
        "100000.0-300000.0": {
          "from": 100000.0,
          "to": 300000.0,
          "doc_count": 1
        },
        "300000.0-*": {
          "from": 300000.0,
          "doc_count": 2
        }
      }
    }
  }
}

Также можно настроить ключ для каждого диапазона:

POST /museums/_search?size=0
{
  "aggs": {
    "rings_around_amsterdam": {
      "geo_distance": {
        "field": "location",
        "origin": "52.3760, 4.894",
        "ranges": [
          { "to": 100000, "key": "first_ring" },
          { "from": 100000, "to": 300000, "key": "second_ring" },
          { "from": 300000, "key": "third_ring" }
        ],
        "keyed": true
      }
    }
  }
}

Ответ:

{
  ...
  "aggregations": {
    "rings_around_amsterdam": {
      "buckets": {
        "first_ring": {
          "from": 0.0,
          "to": 100000.0,
          "doc_count": 3
        },
        "second_ring": {
          "from": 100000.0,
          "to": 300000.0,
          "doc_count": 1
        },
        "third_ring": {
          "from": 300000.0,
          "doc_count": 2
        }
      }
    }
  }
}

© 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/7.17/search-aggregations-bucket-geodistance-aggregation.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API