elasticsearch導入json數(shù)據(jù)

導入json數(shù)據(jù)到es

  • 每條記錄必須有一條對應的index聲明兆解。json文件應符合Bulk API要求
  • json文件中每條數(shù)據(jù)前需包含index信息(index/type/id...)
curl -H 'Content-Type: application/x-ndjson'  -s -XPOST localhost:9200/_bulk --data-binary @accounts.json
{"index":{"_index":"index2","_type":"type2","_id":0}}
{"age":10,"name":"jim"}
    {"index":{"_index":"index2","_type":"type2","_id":1}}
{"age":16,"name":"tom"}
  • 若導入文件中為同一個index(/index/type)绊序,則可在url中聲明默認index(/index/type)放仗,則json文件中無須聲明index和type济欢,同時牧嫉,支持部分記錄顯示聲明index和type烫映。
curl -H 'Content-Type: application/x-ndjson'  -s -XPOST localhost:9200/index1/_bulk --data-binary @accounts.json #URL中聲明默認index
curl -H 'Content-Type: application/x-ndjson'  -s -XPOST localhost:9200/index1/type1/_bulk --data-binary @accounts.json #URL中聲明默認index/type
{"index":{}
{"age":6,"name":"bob"}
{"index":{"_id":"2"}}
{"age":10,"name":"jim"}
{"index":{"_id":"6"}}
{"index":{"_type":"type2","_id":1}}
{"age":16,"name":"tom"}
{"index":{"_index":"index2","_type":"type3","_id":1}}
{"age":20,"name":"lucy"}
  • 可直接導入符合格式要求的json让簿,無須事先創(chuàng)建mapping,es可根據(jù)json數(shù)據(jù)自動創(chuàng)建漠畜。
    也可事先聲明mapping币他,,進行自定義設(shè)置
  • curl命令導入示例

導入shapefile到es

查閱眾多資料后憔狞,理論上有如下幾種方式:

  1. 使用GDAL直接將shapefile導入ES蝴悉,失敗
  2. 使用GDAL(或ArcMap)將shapefile導成json文件,使用curl命令導入json文件
    說明:生成的json文件格式不符合Bulk API要求瘾敢,需處理后方能導入
  3. 使用Arcpy編寫腳本拍冠,將shapefile導出成符合Bulk要求的json,再使用curl命令導入(或腳本實現(xiàn))
  4. 使用ArcMap導出geojson(或使用Arcpy)簇抵,使用python(java)解析json文件庆杜,使用Bulk API編寫腳本導入ES

其中需注意的問題為:

  1. 使用GDAL或ArcMap導出的geojson格式Bulk API要求的數(shù)據(jù)格式不同
  2. 數(shù)據(jù)需符合Geo-shape datatypeGeo-point datatype方能使用curl命令導入

綜上,最終選擇使用第4種方法解決正压,使用GDAL將shapefile導出成geojson文件欣福,再使用python elasticsearch bulk API編寫腳本责球,解析geojson并導入ES焦履。

1. shapefile to es(失斖厝啊)

GDAL for ES Driver提供shapefile直接導入ES的方法,但導入時報錯

ogr2ogr -f "ElasticSearch" http://localhost:9200 my_shapefile.shp

#ERROR 1: HTTP error code : 405
#ERROR 8: Could not connect to server
#ElasticSearch driver failed to create http://localhost:9200/

2. 通過json文件中轉(zhuǎn)(需處理json文件格式)

另外一種方式為使用ogr2ogr工具將shapefile轉(zhuǎn)換為geojson文件嘉裤,再將geojson文件導入ES郑临。

2.1 shapefile to geojson

How to convert and import Arc Shapefile from Zillow into an elastic search database?
Ask

ogr2ogr -f GeoJSON  map1.geojson map.shp

生成的json文件格式如下,不包含index信息屑宠,Bulk API無法直接導入厢洞。

{
"type": "FeatureCollection",
                                                                                
"features": [
{ "type": "Feature", "properties": { "ID_0": 45, "NAME_1": "Anhui" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 119.632111, 31.139344000000108 ], [ 119.644439000000148, 31.115657 ], [ 119.624672, 31.084624000000133 ] ] ] } } 
{ "type": "Feature", "properties": { "ID_0": 45, "NAME_1": "Beijing" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 117.379737, 40.226871 ], [ 117.382896, 40.208718000000147 ], [ 117.369484, 40.190997 ] ] ] } }
]
}

2.2 create index mapping

Indexing Geo Shapes
可針對geo字段和重點字段進行mapping,其余字段導入時自動生成典奉。

PUT /gis1
{
  "mappings": {
    "province1": {
       "properties": {
          "location": {
             "type": "geo_shape"
          },          
          "ID_0": {
             "type": "text"
          },
            "NAME_1": {
             "type": "text"
          }
       }
    }
  }
}

2.3 import json

curl -H 'Content-Type: application/x-ndjson' -XPOST 'http://localhost:9200/gis1/province1/_bulk?pretty' --data-binary @map1.geojson

#報錯:"type":"json_e_o_f_exception","reason":"Unexpected end-of-input: expected close marker for Object (start marker at [Source: org.elasticsearch.transport.netty4.ByteBufStreamInput@1ffa375d; line: 1, column: 1])\n at [Source: org.elasticsearch.transport.netty4.ByteBufStreamInput@1ffa375d; line: 1, column: 3]"

需將數(shù)據(jù)改造成如下格式后躺翻,再使用bulk命令導入。

{"index":{"_id":"1"}}
{ "type": "Feature", "properties": { "ID_0": 45, "NAME_1": "Zhejiang" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 121.187362, 27.86903100000012 ], [ 121.190140000000156, 27.847919 ], [ 121.156249, 27.823749000000134 ]] ] ] } }
{"index":{"_id":"2"}}
{ "type": "Feature", "properties": { "ID_0": 46, "NAME_1": "Jiangsu" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 121.187362, 27.86903100000012 ], [ 121.190140000000156, 27.847919 ], [ 121.156249, 27.823749000000134 ]] ] ] } }

4. python腳本導入GDAL生成的geojson文件

# rasa 20180212
# 使用ES python api插入geojson面數(shù)據(jù)(map.geojson)

import json
from elasticsearch import Elasticsearch
from elasticsearch.helpers import bulk


def set_mapping(es, index_name="content_engine", doc_type_name="en"):
    my_mapping = {
        doc_type_name: {
            "properties": {
                "location": {
                    "type": "geo_shape"
                },
                "ID_0": {
                    "type": "text"
                },
                "NAME_1": {
                    "type": "text"
                }
            }
        }
    }

    # ignore 404 and 400
    es.indices.delete(index=index_name, ignore=[400, 404])
    print("delete_index")

    # ignore 400 cause by IndexAlreadyExistsException when creating an index
    create_index = es.indices.create(index=index_name, ignore=400)
    mapping_index = es.indices.put_mapping(index=index_name, doc_type=doc_type_name, body=my_mapping)
    if create_index["acknowledged"] is not True or mapping_index["acknowledged"] is not True:
        print("Index creation failed...")


def set_data(es, input_file, index_name, doc_type_name="en"):
    with open(input_file, 'r') as f:
        data = json.load(f)

    features = data["features"]

    ACTIONS = []
    i = 0
    count = 0

    for feature in features:
        action = {}

        if (feature["geometry"]["type"] == "Polygon"):  # 判斷geometry類型為polygon
            action = {
                "_index": index_name,
                "_type": doc_type_name,
                "_source": {
                    "ID_0": feature["properties"]["ID_0"],
                    "NAME_1": feature["properties"]["NAME_1"],
                    "location": {
                        "type": "polygon",
                        "coordinates": feature["geometry"]["coordinates"]
                    }
                }
            }
        else:  # geometry類型為multipolygon
            action = {
                "_index": index_name,
                "_type": doc_type_name,
                "_source": {
                    "ID_0": feature["properties"]["ID_0"],
                    "NAME_1": feature["properties"]["NAME_1"],
                    "location": {
                        "type": "multipolygon",
                        "coordinates": feature["geometry"]["coordinates"]
                    }
                }
            }

        i += 1
        print("prepare insert:  %s" % feature["properties"]["NAME_1"])
        print("type:  %s" % feature["geometry"]["type"])
        ACTIONS.append(action)
        if (i == 5):
            success, _ = bulk(es, ACTIONS, index=index_name, raise_on_error=True)
            count += success
            i = 0
            ACTIONS = []
            print("insert %s lines" % count)

    success, _ = bulk(es, ACTIONS, index=index_name, raise_on_error=True)
    count += success
    print("insert %s lines" % count)


if __name__ == '__main__':
    # es = Elasticsearch(hosts=["127.0.0.1:9200"], http_auth=('elastic','changeme'),timeout=5000)
    es = Elasticsearch(hosts=["127.0.0.1:9200"], timeout=5000)
    set_mapping(es, "gis6", "province")

    # geojson文件為ogr2ogr生成格式

    # set_data(es, "./data/map-fujian.geojson", "gis6", "province")  # multipolygon
    # set_data(es, "./data/map-anhui.geojson", "gis6", "province") # polygon
    set_data(es, "./data/map-full.geojson", "gis6", "province")  # polygon & multipolygon
    # set_data(es, "./data/map.geojson", "gis6", "province")       # polygon

問題

1.使用python bulk導入multipolygon時報錯:Invalid LinearRing found. Found a single coordinate when expecting a coordinate array

sourcecode 638行

原因

  • 同一個geojson文件中存在存在類型為polygon和multipolygon的feature
  • 設(shè)定mapping為polygon卫玖,插入multipolygon數(shù)據(jù)會報錯:
    invalid number of points in LinearRing (found [1] - must be >= [4])公你;
  • 設(shè)定mapping為multipolygon,插入polygon數(shù)據(jù)會報錯:
    Invalid LinearRing found. Found a single coordinate when expecting a coordinate array

解決方法
判斷feature的類型假瞬,創(chuàng)建的mapping不同陕靠,ES支持同一個type中同時存儲polygon/multipolygon

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市脱茉,隨后出現(xiàn)的幾起案子剪芥,更是在濱河造成了極大的恐慌,老刑警劉巖琴许,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件税肪,死亡現(xiàn)場離奇詭異,居然都是意外死亡虚吟,警方通過查閱死者的電腦和手機寸认,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來串慰,“玉大人偏塞,你說我怎么就攤上這事“铞辏” “怎么了灸叼?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長庆捺。 經(jīng)常有香客問我古今,道長,這世上最難降的妖魔是什么滔以? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任捉腥,我火速辦了婚禮,結(jié)果婚禮上你画,老公的妹妹穿的比我還像新娘抵碟。我一直安慰自己桃漾,他們只是感情好,可當我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布拟逮。 她就那樣靜靜地躺著撬统,像睡著了一般。 火紅的嫁衣襯著肌膚如雪敦迄。 梳的紋絲不亂的頭發(fā)上恋追,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天,我揣著相機與錄音罚屋,去河邊找鬼苦囱。 笑死,一個胖子當著我的面吹牛脾猛,可吹牛的內(nèi)容都是我干的沿彭。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼尖滚,長吁一口氣:“原來是場噩夢啊……” “哼喉刘!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起漆弄,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤睦裳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后撼唾,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體廉邑,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年倒谷,在試婚紗的時候發(fā)現(xiàn)自己被綠了蛛蒙。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡渤愁,死狀恐怖牵祟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情抖格,我是刑警寧澤诺苹,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站雹拄,受9級特大地震影響收奔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜滓玖,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一坪哄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦翩肌、人聲如沸饰剥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至绷蹲,卻和暖如春棒卷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背祝钢。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工比规, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人拦英。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓蜒什,卻偏偏與公主長得像,于是被迫代替她去往敵國和親疤估。 傳聞我的和親對象是個殘疾皇子灾常,可洞房花燭夜當晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容