#elasticsearch #geojson #shapefile
#elasticsearch #geojson #шейп-файл
Вопрос:
Я пытаюсь сохранить пространственные данные в виде geojson, файлов CSV и файлов формы в elasticsearch С ИСПОЛЬЗОВАНИЕМ PYTHON.Я новичок в elasticsearch и даже после ознакомления с документацией я не могу успешно его проиндексировать. Будем признательны за любую помощь.
пример файла geojson :
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"ID_0": 105,
"ISO": "IND",
"NAME_0": "India",
"ID_1": 1288,
"NAME_1": "Telangana",
"ID_2": 15715,
"NAME_2": "Telangana",
"VARNAME_2": null,
"NL_NAME_2": null,
"HASC_2": "IN.TS.AD",
"CC_2": null,
"TYPE_2": "State",
"ENGTYPE_2": "State",
"VALIDFR_2": "Unknown",
"VALIDTO_2": "Present",
"REMARKS_2": null,
"Shape_Leng": 8.103535,
"Shape_Area": 127258717496
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
79.14429367552918,
19.500257885106404
],
[
79.14582245808431,
19.498859172536427
],
[
79.14600496956801,
19.498823981691853
],
[
79.14966523737327,
19.495821705263914
]
]
]
}
}
]
}
Комментарии:
1. Можете ли вы показать свой файл geojson? (или его часть)
2. {«type»: «FeatureCollection», «features»: [{«тип»:»Функция», «properties»:{«ID_0″:105,»ISO»:»IND»,»NAME_0″:»India»,»ID_1″:1288,»NAME_1″:»Telangana»,»ID_2″:15715,»NAME_2″:»Telangana»,»VARNAME_2″:null,»NL_NAME_2″:null,»HASC_2″:»IN.TS.AD»,»CC_2″:null,»TYPE_2″:»State»,»ENGTYPE_2″:»State»,»VALIDFR_2″:»Unknown»,»VALIDTO_2″:»Present»,»REMARKS_2″:null,»Shape_Leng»:8.103535,»Shape_Area»:127258717496},»geometry»:{«type»:»Polygon»,»coordinates»:[[[79.14429367552918,19.500257885106404],[79.14582245808431,19.498859172536427],[79.14600496956801,19.498823981691853],
3. Пожалуйста, обновите свой вопрос с его помощью
4. Забавно, я только что прочитал документацию по elasticsearch.co и действительно, в главе «Как проиндексировать файл geosjon …» показан только документ geojson, но не то, как его проиндексировать.
5. @intern ты когда-нибудь это понимал?
Ответ №1:
Код
import geojson
from datetime import datetime
from elasticsearch import Elasticsearch, helpers
def geojson_to_es(gj):
for feature in gj['features']:
date = datetime.strptime("-".join(feature["properties"]["event_date"].split('-')[0:2]) "-" feature["properties"]["year"], "%d-%b-%Y")
feature["properties"]["timestamp"] = int(date.timestamp())
feature["properties"]["event_date"] = date.strftime('%Y-%m-%d')
yield feature
with open("GeoObs.json") as f:
gj = geojson.load(f)
es = Elasticsearch(hosts=[{'host': 'localhost', 'port': 9200}])
k = ({
"_index": "YOUR_INDEX",
"_source": feature,
} for feature in geojson_to_es(gj))
helpers.bulk(es, k)
Объяснение
with open("GeoObs.json") as f:
gj = geojson.load(f)
es = Elasticsearch(hosts=[{'host': 'localhost', 'port': 9200}])
Эта часть кода загружает внешний файл geojson, затем подключается к Elasticsearch.
k = ({
"_index": "conflict-data",
"_source": feature,
} for feature in geojson_to_es(gj))
helpers.bulk(es, k)
()
s здесь создает генератор, который мы будем передавать helpers.bulk(es, k)
. Помните _source
, что исходные данные такие же, как в Elasticsearch, то есть: наш необработанный JSON. _index
это просто индекс, в который мы хотим поместить наши данные. Вы увидите другие примеры с _doc
здесь. Это часть типов сопоставления и больше не существует в Elasticsearch 7.X .
def geojson_to_es(gj):
for feature in gj['features']:
date = datetime.strptime("-".join(feature["properties"]["event_date"].split('-')[0:2]) "-" feature["properties"]["year"], "%d-%b-%Y")
feature["properties"]["timestamp"] = int(date.timestamp())
feature["properties"]["event_date"] = date.strftime('%Y-%m-%d')
yield feature
Функция geojson
использует генератор для создания событий. Функция генератора будет вместо возврата и завершения resume at the keyword
выдавать` после каждого вызова. В этом случае мы генерируем наши функции GeoJSON. В моем коде вы также видите:
date = datetime.strptime("-".join(feature["properties"]["event_date"].split('-')[0:2]) "-" feature["properties"]["year"], "%d-%b-%Y")
feature["properties"]["timestamp"] = int(date.timestamp())
feature["properties"]["event_date"] = date.strftime('%Y-%m-%d')
Это всего лишь пример манипулирования данными в JSON перед отправкой их в Elasticsearch.
Ключ находится в вашем файле сопоставления, у вас должно быть что-то помечено как geo_point
или geo_shape
. Эти типы данных — то, как Elasticsearch распознает географические данные. Пример из моего файла сопоставления:
...
{
"properties": {
"geometry": {
"properties": {
"coordinates": {
"type": "geo_point"
},
"type": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
...
То есть перед загрузкой ваших данных GeoJSON с помощью Python вам необходимо создать свой индекс, а затем применить файл сопоставления, который включает в себя либо geo_shape
, либо geo_point
используя что-то вроде:
curl -X PUT "localhost:9200/YOUR_INDEX?pretty"
curl -X PUT localhost:9200/YOUR_INDEX/_mapping?pretty -H "Content-Type: application/json" -d @mapping.json
Ответ №2:
Вы должны разделить объекты GeoJSON на (1) геометрию и (2) свойства / атрибуты. части. Вы не можете напрямую индексировать объекты GeoJSON и коллекции объектов (см. Документацию), в качестве типа поля поддерживается только геометрическая часть.
Таким образом, ваш окончательный индексируемый документ будет выглядеть несколько сглаженным:
{
"ID_0": 105,
"ISO": "IND",
"NAME_0": "India",
"ID_1": 1288,
"NAME_1": "Telangana",
"ID_2": 15715,
"NAME_2": "Telangana",
"VARNAME_2": null,
"NL_NAME_2": null,
"HASC_2": "IN.TS.AD",
"CC_2": null,
"TYPE_2": "State",
"ENGTYPE_2": "State",
"VALIDFR_2": "Unknown",
"VALIDTO_2": "Present",
"REMARKS_2": null,
"Shape_Leng": 8.103535,
"Shape_Area": 127258717496,
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
79.14429367552918,
19.500257885106404
],
[
79.14582245808431,
19.498859172536427
],
[
79.14600496956801,
19.498823981691853
],
[
79.14966523737327,
19.495821705263914
]
]
]
}
}
Комментарии:
1. Ответили давно, но если кто-нибудь читает; Есть ли тип данных для «Shape_Area» или Leng? Я просто использую значение с плавающей точкой / long или Point?
2. Для них нет специального типа — вы должны придерживаться простых числовых типов в ES: elastic.co/guide/en/elasticsearch/reference/current/number.html
3. Как бы вы на самом деле выполнили индексацию данных?