ElasticSearch 7.13 기반 책 리뷰
오래전에 “시작하세요! 엘라스틱서치” 라는 책을 구매해 본적이 있다. 지금도 소장하고 있는데, 엘라스틱서치에 대한 기본적인 개념을 익히는데 손색이 없는 책이라 평가하고 싶다. 단, 내가 볼때에 엘라스틱서치에 버전이 6.4 이다 보니 없어져버린 기능들은, 예를들어 펫싯, 볼 필요가 없었다.
오늘은 최신의 ElasticSearch 7.13 버전에서 이 책에 내용을 한번 살펴보고자 한다. 엘라스틱서치는 버전이 올라감에 따라 변경된 부분이 상당히 많아진다는 점을 생각해보면 꽤 도움이 될법한 내용들이라 생각한다.
엘라스틱서치의 데이터 구조 – 타입(Type) 없어짐
엘라스틱서치의 데이터 구조를 설명에서 인덱스(Index), 타입(Type), 도큐먼트(Document) 단위로 이루어진다고 설명했다. 하지만 엘라스틱서치 7.x 로 버전이 높아짐에 따라 타입은 이제 없다. 이에 대해서 엘라스틱서치 개발사에서 다음과 같은 페이지를 제공해 설명해 주고 있다.
위 문서를 보면 예를들어서 타입이 뭔지 설명하고 있으며 왜 없앴는지 타입을 이용했던 방법의 대안은 무엇인지 상세히 설명해 주고 있다.
그런데, 과연 타입(Type) 은 없어졌을까?
PUT 메소드 대신 POST 그리고 Content-Type 지정
책에 다음과 같은 예제가 나온다.
1 2 3 4 5 6 7 8 |
curl -XPUT http://192.168.96.40:9200/books/book/1 -d ' { "title": "Elasticsearch Guide", "author": "Kim", "date": "2014-05-01", "pages": 250 }' {"error":"Content-Type header [application/x-www-form-urlencoded] is not supported","status":406} |
하지만 위와 같이 오류가 발생한다.
다음과 같이 Header 에 json 컨텐츠 타입을 지정해 줘야 한다.
1 2 3 4 5 6 7 8 |
curl -s -H "Content-Type: application/json" -XPUT http://192.168.96.40:9200/books/book/1 -d ' > { > "title": "Elasticsearch Guide", > "author": "Kim", > "date": "2014-05-01", > "pages": 250 > }' {"_index":"books","_type":"book","_id":"1","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":0,"_primary_term":1} |
앞서 매핑 타입이 없어졌다고 했지만 데이터를 입력하면 잘 들어 간다. GET 메소드를 이용한 조회도 잘 된다. 하지만 이것은 한가지 트릭과 같은데, 매핑에는 타입이 안나온다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
curl -XGET http://192.168.96.40:9200/books/_mapping?pretty { "books" : { "mappings" : { "properties" : { "author" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } }, "date" : { "type" : "date" }, "pages" : { "type" : "long" }, "title" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } } } } } } |
매핑 결과를 보면 타입(Type) 이 안나온다.
hotels 매핑 오류
책에는 hotels 인덱스 생성을 위해서 매핑(Mapping) 을 먼저 작성해 주는데 다음과 같다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
curl -s -H "Content-Type: application/json" -XPUT http://192.168.96.40:9200/hotels/?pretty=true -d ' { "mappings" : { "hotel" : { "properties" : { "name" : { "type": "string" }, "stars" : { "type": "long" }, "rooms" : { "type": "long" }, "location" : { "type": "geo_point" }, "city" : { "type": "string" }, "address" : { "type": "string" }, "internet" : { "type": "boolean" }, "service" : { "type": "string", "idnex": "not_analyzed" }, "checkin" : { "type": "date", "format": "dateOptionalTime" } } } } }' { "error" : { "root_cause" : [ { "type" : "mapper_parsing_exception", "reason" : "Root mapping definition has unsupported parameters: [hotel : {properties={rooms={type=long}, address={type=string}, checkin={format=dateOptionalTime, type=date}, city={type=string}, service={idnex=not_analyzed, type=string}, name={type=string}, location={type=geo_point}, stars={type=long}, internet={type=boolean}}}]" } ], "type" : "mapper_parsing_exception", "reason" : "Failed to parse mapping [_doc]: Root mapping definition has unsupported parameters: [hotel : {properties={rooms={type=long}, address={type=string}, checkin={format=dateOptionalTime, type=date}, city={type=string}, service={idnex=not_analyzed, type=string}, name={type=string}, location={type=geo_point}, stars={type=long}, internet={type=boolean}}}]", "caused_by" : { "type" : "mapper_parsing_exception", "reason" : "Root mapping definition has unsupported parameters: [hotel : {properties={rooms={type=long}, address={type=string}, checkin={format=dateOptionalTime, type=date}, city={type=string}, service={idnex=not_analyzed, type=string}, name={type=string}, location={type=geo_point}, stars={type=long}, internet={type=boolean}}}]" } }, "status" : 400 } |
“Root mapping definition has unsupported parameters” 위와같이 오류가 발생 한다. 타입이 문제가 되는 경우라고 볼 수 있다. 위 내용을 수정하면 다음과 같다.
- 매핑 타입 제거
- string 타입을 제거하고 text 로 대체
- not_analyzed 를 false 로 대체
- dateOptionalTime 을 date_optional_time 으로 변경
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
curl -s -H "Content-Type: application/json" -XPUT http://192.168.96.40:9200/hotels/?pretty=true -d ' { "mappings" : { "properties" : { "name" : { "type": "text" }, "stars" : { "type": "long" }, "rooms" : { "type": "long" }, "location" : { "type": "geo_point" }, "city" : { "type": "text" }, "address" : { "type": "text" }, "internet" : { "type": "boolean" }, "service" : { "type": "text", "index": "false" }, "checkin" : { "type": "date", "format": "date_optional_time" } } } }' { "acknowledged" : true, "shards_acknowledged" : true, "index" : "hotels" } |
성공적으로 생성 됐다.
Bulk 데이터 임포트
대량의 데이터를 엘라스틱서치에 입력할때에는 벌크(Bulk) api 를 이용한다. 매핑의 타입이 없기 때문에 타입을 제거해야 한다.
1 2 |
{ "create" : { "_index": "hotels", "_type": "hotel"} } ## 여기서 type 을 없애야 한다. { "create" : { "_index": "hotels" } } |
그리고 벌크 API 를 이용할때에는 다음과 같은 Content-Type 을 입력해줘야 한다.
1 |
curl -s -H "Content-Type: application/x-ndjson" -XPOST http://192.168.96.40:9200/_bulk?pretty=true --data-binary "@6_1_hotels.json" |
위와같이 application/x-ndjson 을 지정해 줘야 한다.