Spec-Zone.ru › Elasticsearch 8
›Elasticsearch Guide [8.17] ›Отображение ›Типы данных полей

Тип поля Geopoint

Поля типа geo_point принимают пары широты-долготы, которые могут использоваться:

  • для поиска географических точек в пределах прямоугольника, на определённом расстоянии от центральной точки или в рамках geo_shape запроса (например, точки в полигоне).
  • для агрегирования документов по расстоянию от центральной точки.
  • для агрегирования документов по географическим сетям: либо geo_hash, geo_tile или geo_hex.
  • для агрегирования географических точек в траекторию с помощью метрики geo_line.
  • для добавления расстояния в релевантность документа.
  • для сортировки документов по расстоянию.

Как и для geo_shape и point, geo_point можно указать в форматах GeoJSON и Well-Known Text. Однако, для удобства и по историческим причинам поддерживаются дополнительные форматы. В целом, существует шесть способов указания геокоординат, как показано ниже:

resp = client.indices.create(
    index="my-index-000001",
    mappings={
        "properties": {
            "location": {
                "type": "geo_point"
            }
        }
    },
)
print(resp)

resp1 = client.index(
    index="my-index-000001",
    id="1",
    document={
        "text": "Geopoint as an object using GeoJSON format",
        "location": {
            "type": "Point",
            "coordinates": [
                -71.34,
                41.12
            ]
        }
    },
)
print(resp1)

resp2 = client.index(
    index="my-index-000001",
    id="2",
    document={
        "text": "Geopoint as a WKT POINT primitive",
        "location": "POINT (-71.34 41.12)"
    },
)
print(resp2)

resp3 = client.index(
    index="my-index-000001",
    id="3",
    document={
        "text": "Geopoint as an object with 'lat' and 'lon' keys",
        "location": {
            "lat": 41.12,
            "lon": -71.34
        }
    },
)
print(resp3)

resp4 = client.index(
    index="my-index-000001",
    id="4",
    document={
        "text": "Geopoint as an array",
        "location": [
            -71.34,
            41.12
        ]
    },
)
print(resp4)

resp5 = client.index(
    index="my-index-000001",
    id="5",
    document={
        "text": "Geopoint as a string",
        "location": "41.12,-71.34"
    },
)
print(resp5)

resp6 = client.index(
    index="my-index-000001",
    id="6",
    document={
        "text": "Geopoint as a geohash",
        "location": "drm3btev3e86"
    },
)
print(resp6)

resp7 = client.search(
    index="my-index-000001",
    query={
        "geo_bounding_box": {
            "location": {
                "top_left": {
                    "lat": 42,
                    "lon": -72
                },
                "bottom_right": {
                    "lat": 40,
                    "lon": -74
                }
            }
        }
    },
)
print(resp7)
response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      properties: {
        location: {
          type: 'geo_point'
        }
      }
    }
  }
)
puts response

response = client.index(
  index: 'my-index-000001',
  id: 1,
  body: {
    text: 'Geopoint as an object using GeoJSON format',
    location: {
      type: 'Point',
      coordinates: [
        -71.34,
        41.12
      ]
    }
  }
)
puts response

response = client.index(
  index: 'my-index-000001',
  id: 2,
  body: {
    text: 'Geopoint as a WKT POINT primitive',
    location: 'POINT (-71.34 41.12)'
  }
)
puts response

response = client.index(
  index: 'my-index-000001',
  id: 3,
  body: {
    text: "Geopoint as an object with 'lat' and 'lon' keys",
    location: {
      lat: 41.12,
      lon: -71.34
    }
  }
)
puts response

response = client.index(
  index: 'my-index-000001',
  id: 4,
  body: {
    text: 'Geopoint as an array',
    location: [
      -71.34,
      41.12
    ]
  }
)
puts response

response = client.index(
  index: 'my-index-000001',
  id: 5,
  body: {
    text: 'Geopoint as a string',
    location: '41.12,-71.34'
  }
)
puts response

response = client.index(
  index: 'my-index-000001',
  id: 6,
  body: {
    text: 'Geopoint as a geohash',
    location: 'drm3btev3e86'
  }
)
puts response

response = client.search(
  index: 'my-index-000001',
  body: {
    query: {
      geo_bounding_box: {
        location: {
          top_left: {
            lat: 42,
            lon: -72
          },
          bottom_right: {
            lat: 40,
            lon: -74
          }
        }
      }
    }
  }
)
puts response
const response = await client.indices.create({
  index: "my-index-000001",
  mappings: {
    properties: {
      location: {
        type: "geo_point",
      },
    },
  },
});
console.log(response);

const response1 = await client.index({
  index: "my-index-000001",
  id: 1,
  document: {
    text: "Geopoint as an object using GeoJSON format",
    location: {
      type: "Point",
      coordinates: [-71.34, 41.12],
    },
  },
});
console.log(response1);

const response2 = await client.index({
  index: "my-index-000001",
  id: 2,
  document: {
    text: "Geopoint as a WKT POINT primitive",
    location: "POINT (-71.34 41.12)",
  },
});
console.log(response2);

const response3 = await client.index({
  index: "my-index-000001",
  id: 3,
  document: {
    text: "Geopoint as an object with 'lat' and 'lon' keys",
    location: {
      lat: 41.12,
      lon: -71.34,
    },
  },
});
console.log(response3);

const response4 = await client.index({
  index: "my-index-000001",
  id: 4,
  document: {
    text: "Geopoint as an array",
    location: [-71.34, 41.12],
  },
});
console.log(response4);

const response5 = await client.index({
  index: "my-index-000001",
  id: 5,
  document: {
    text: "Geopoint as a string",
    location: "41.12,-71.34",
  },
});
console.log(response5);

const response6 = await client.index({
  index: "my-index-000001",
  id: 6,
  document: {
    text: "Geopoint as a geohash",
    location: "drm3btev3e86",
  },
});
console.log(response6);

const response7 = await client.search({
  index: "my-index-000001",
  query: {
    geo_bounding_box: {
      location: {
        top_left: {
          lat: 42,
          lon: -72,
        },
        bottom_right: {
          lat: 40,
          lon: -74,
        },
      },
    },
  },
});
console.log(response7);
PUT my-index-000001
{
  "mappings": {
    "properties": {
      "location": {
        "type": "geo_point"
      }
    }
  }
}

PUT my-index-000001/_doc/1
{
  "text": "Geopoint as an object using GeoJSON format",
  "location": { 
    "type": "Point",
    "coordinates": [-71.34, 41.12]
  }
}

PUT my-index-000001/_doc/2
{
  "text": "Geopoint as a WKT POINT primitive",
  "location" : "POINT (-71.34 41.12)" 
}

PUT my-index-000001/_doc/3
{
  "text": "Geopoint as an object with 'lat' and 'lon' keys",
  "location": { 
    "lat": 41.12,
    "lon": -71.34
  }
}

PUT my-index-000001/_doc/4
{
  "text": "Geopoint as an array",
  "location": [ -71.34, 41.12 ] 
}

PUT my-index-000001/_doc/5
{
  "text": "Geopoint as a string",
  "location": "41.12,-71.34" 
}

PUT my-index-000001/_doc/6
{
  "text": "Geopoint as a geohash",
  "location": "drm3btev3e86" 
}

GET my-index-000001/_search
{
  "query": {
    "geo_bounding_box": { 
      "location": {
        "top_left": {
          "lat": 42,
          "lon": -72
        },
        "bottom_right": {
          "lat": 40,
          "lon": -74
        }
      }
    }
  }
}

Географическая точка, представленная объектом в формате GeoJSON с ключами type и coordinates.

Географическая точка, представленная POINT в формате Well-Known Text: "POINT(lon lat)"

Географическая точка, представленная объектом с ключами lat и lon.

Географическая точка, представленная массивом в формате: [ lon, lat]

Географическая точка, представленная строкой в формате: "lat,lon".

Географическая точка, представленная геохешем.

Запрос на поиск географических точек, попадающих в прямоугольник.

Географические точки, представленные массивом или строкой

Обратите внимание, что геокоординаты в виде строк упорядочены как lat,lon, в то время как геокоординаты в виде массивов, GeoJSON и WKT упорядочены наоборот: lon,lat.

Причина заключается в истории. Географы традиционно записывали latitude перед longitude, в то время как в современных форматах географических данных, таких как GeoJSON и Well-Known Text, порядок longitude перед latitude (восточная координата перед северной) соответствует математическому соглашению об упорядочении x перед y.

Точка может быть представлена геохешем. Геохеши представляют собой строки, закодированные в base32, из чередующихся битов широты и долготы. Каждый символ в геохеше добавляет дополнительные 5 бит точности. Чем длиннее хеш, тем он точнее. Для целей индексирования геохеши преобразуются в пары широты-долготы. При этом используется только первые 12 символов, поэтому указание более 12 символов в геохеше не увеличивает точность. 12 символов обеспечивают 60 бит, что должно уменьшить возможную ошибку до менее 2 см.

Параметры для полей geo_point

Следующие параметры принимаются полями типа geo_point:

ignore_malformed

Если true, некорректные геокоординаты игнорируются. Если false (по умолчанию), некорректные геокоординаты приводят к исключению и отклонению всего документа. Геокоордината считается некорректной, если широта находится вне диапазона -90 ⇐ широта ⇐ 90, или если долгота находится вне диапазона -180 ⇐ долгота ⇐ 180. Обратите внимание, что это не может быть установлено, если используется параметр script.

ignore_z_value

Если true (по умолчанию), точки с тремя измерениями будут приняты (сохранены в источнике), но будут индексироваться только широта и долгота; третье измерение игнорируется. Если false, геокоординаты, содержащие более чем широту и долготу (два измерения), приводят к исключению и отклонению всего документа. Обратите внимание, что это не может быть установлено, если используется параметр script.

index

Необходимо ли быстрое поиск по полю? Принимает true (по умолчанию) и false. Поля, у которых включены только doc_values, всё ещё могут быть запрошены, но медленнее.

null_value

Принимает значение geopoint, которое используется для явных null значений. По умолчанию null, что означает, что поле считается отсутствующим. Обратите внимание, что это не может быть установлено, если используется параметр script.

on_script_error

Определяет, что делать, если скрипт, определённый параметром script, вызывает ошибку при индексировании. Принимает fail (по умолчанию), что приведет к отклонению всего документа, и continue, что запишет поле в метаданные документа _ignored и продолжит индексирование. Этот параметр может быть установлен только если также установлен параметр script.

script

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

Использование geopoints в скриптах

При обращении к значению geopoint в скрипте, значение возвращается как объект GeoPoint, который позволяет получить доступ к значениям .lat и .lon соответственно:

def geopoint = doc['location'].value;
def lat      = geopoint.lat;
def lon      = geopoint.lon;

Для повышения производительности лучше напрямую обращаться к значениям lat/lon:

def lat      = doc['location'].lat;
def lon      = doc['location'].lon;

Синтетический источник

Синтетический _source доступен только для индексов TSDB (индексы, у которых index.mode установлено в time_series). Для других индексов синтетический _source находится в техническом превью. Функции в техническом превью могут быть изменены или удалены в будущих выпусках. Elastic будет работать над устранением любых проблем, но функции в техническом превью не подпадают под SLA поддержки официальных функций GA.

Синтетический источник может сортировать поля geo_point (сначала по широте, а затем по долготе) и сокращает их до сохранённой точности. Например:

resp = client.indices.create(
    index="idx",
    settings={
        "index": {
            "mapping": {
                "source": {
                    "mode": "synthetic"
                }
            }
        }
    },
    mappings={
        "properties": {
            "point": {
                "type": "geo_point"
            }
        }
    },
)
print(resp)

resp1 = client.index(
    index="idx",
    id="1",
    document={
        "point": [
            {
                "lat": -90,
                "lon": -80
            },
            {
                "lat": 10,
                "lon": 30
            }
        ]
    },
)
print(resp1)
const response = await client.indices.create({
  index: "idx",
  settings: {
    index: {
      mapping: {
        source: {
          mode: "synthetic",
        },
      },
    },
  },
  mappings: {
    properties: {
      point: {
        type: "geo_point",
      },
    },
  },
});
console.log(response);

const response1 = await client.index({
  index: "idx",
  id: 1,
  document: {
    point: [
      {
        lat: -90,
        lon: -80,
      },
      {
        lat: 10,
        lon: 30,
      },
    ],
  },
});
console.log(response1);
PUT idx
{
  "settings": {
    "index": {
      "mapping": {
        "source": {
          "mode": "synthetic"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "point": { "type": "geo_point" }
    }
  }
}
PUT idx/_doc/1
{
  "point": [
    {"lat":-90, "lon":-80},
    {"lat":10, "lon":30}
  ]
}

Преобразуется в:

{
  "point": [
    {"lat":-90.0, "lon":-80.00000000931323},
    {"lat":9.999999990686774, "lon":29.999999972060323}
   ]
}

© 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/geo-point.html

Spec-Zone.ru

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