성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Working with Rust Libraries from C#...
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>윈도우 환경에서 curl.exe를 이용한 elasticsearch 6.x 기본 사용법</h1> <p> 사용을 위해 elasticsearch를 설치해야겠죠? ^^ 윈도우 10 운영체제에 다음과 같이 간단하게 설치할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 1. Java 8 (x64) 설치 (JDK 또는 JRE) 2. <a target='tab' href='https://www.elastic.co/downloads/elasticsearch'>https://www.elastic.co/downloads/elasticsearch</a>로부터 ".zip" 파일 다운로드 6.3.2 버전 <a target='tab' href='https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.3.2.zip'>https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.3.2.zip</a> 3. bin\elasticsearch.bat 파일을 메모장에서 편집(자신의 환경에 맞게 경로 설정) SET JAVA_HOME=C:\Program Files\Java\jdk1.8.0_131 4. bin\elasticsearch.bat 파일 실행 5. 다음의 명령어를 실행해서 정상 동작하는지 확인 <span style='color: blue; font-weight: bold'>curl http://localhost:9200/</span> 그 결과로 아래와 같은 식의 내용이 출력되면 OK! { "name" : "Vld1Cby", "cluster_name" : "elasticsearch", "cluster_uuid" : "WYC...[생략]...WXQ", "version" : { "number" : "6.3.2", "build_flavor" : "default", "build_type" : "zip", "build_hash" : "053779d", "build_date" : "2018-07-20T05:20:23.451332Z", "build_snapshot" : false, "lucene_version" : "7.3.1", "minimum_wire_compatibility_version" : "5.6.0", "minimum_index_compatibility_version" : "5.0.0" }, "tagline" : "You Know, for Search" } </pre> <br /> 이것으로 설치가 모두 끝났습니다. ^^<br /> <br /> <hr style='width: 50%' /><br /> <br /> 이제 사용법을 알아야 하겠죠? ^^<br /> <br /> 근데, 사용법이 정말 쉽습니다. 약간의 웹 검색만 해보면 대충 알 수 있을 정도입니다. 물론 고급 사용자의 위치까지 가려면 어느 정도 더 공부를 해야겠지만 초기 개념만 잡는 식이라면 쉽게 테스트하면서 익힐 수 있습니다.<br /> <br /> 기존의 관계형 데이터베이스 사용자를 위해 DB와 비교해서 설명하면 대충 다음과 같습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > elasticsearch의 index == DB의 데이터베이스 elasticsearch의 type == DB의 테이블 </pre> <br /> 그리고 이를 위한 RESTful 쿼리가 다음과 같은 형식으로 제공됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > http://host:port/(index)/(type)/(action|id) </pre> <br /> 여기서 host:port는 elasticsearch를 localhost에서 테스트하는 경우 (특별히 바꾸지 않았다면) 다음과 같이 정해집니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > http://localhost:9200/ </pre> <br /> (index)와 (type)은 명시적으로 생성해 주거나 아니면, 그냥 데이터를 전달해서 스키마를 elasticsearch가 자동으로 추론하도록 만들 수 있습니다. 예를 들어, 여러분들이 가진 데이터 중에 "회원 목록"이 있다고 가정해 보겠습니다. 그리고 회원에 대한 DB 스키마는 다음과 같습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > name: string age: int address: string registered: date </pre> <br /> 자동 추론 방법으로 (index)/(type)을 생성하고 싶다면 다음과 같이 그냥 데이터를 HTTP PUT 메서드를 이용해 elasticsearch에 던지면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > curl -XPUT "http://localhost:9200/my_org/member/1" -H "Content-Type: application/json" -d "{ "name" : "tester", "age": 16, "address": "seoul KOREA", "registered" : "2017-04-29T10:16:00" }" </pre> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > curl -XPUT "http://localhost:9200/my_org/member/1" -H "Content-Type: application/json" -d "{ \"name\" : \"tester\", \"age\": 16, \"address\": \"seoul KOREA\", \"registered\" : \"2017-04-29T10:16:00\" }" {"_index":"my_org","_type":"member","_id":"1","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":0,"_primary_term":1} // 서버 로그 [2018-08-09T09:26:19,168][INFO ][o.e.c.m.MetaDataMappingService] [Vld1Cby] [my_org/g55350WDSDaHKWMBm9Yi8Q] create_mapping [member] </pre> <br /> 그럼, elasticsearch는 URL의 (index)에 해당하는 "my_org" 인덱스가 있는지 검사하고 없으면 생성합니다. 그다음 URL의 (type)에 해당하는 스키마가 있는지 역시 검사해 보고 없으면 HTTP PUT의 Body로 들어온 JSON 데이터를 보고 스키마를 유추해 "member"라는 이름으로 생성해 둡니다. 마지막의 (action|id)는 해당 데이터에 대한 식별자가 됩니다.<br /> <br /> 혹시 저 회원의 주소(address)가 변경되었다면 어떻게 해야 할까요? 당연히 (index), (type), (action|id)만 알고 있다면 다음과 같은 식으로 덮어쓰는 것이 가능합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > curl -XPUT "http://localhost:9200/my_org/member/1" -H "Content-Type: application/json" -d "{ "name" : "tester", "age": 16, "address": "daejeon KOREA", "registered":"2017-04-29T10:16:00" }" </pre> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C:\temp> curl -XPUT "http://localhost:9200/my_org/member/1" -H "Content-Type: application/json" -d "{ \"name\" : \"tester\", \"age\": 16, \"address\": \"daejeon KOREA\", \"registered\":\"2017-04-29T10:16:00\" }" {"_index":"my_org","_type":"member","_id":"1","_version":2,"result":"updated","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":1,"_primary_term":1} </pre> <br /> <span style='text-decoration: line-through'>혹은, 특정 필드만 변경되었다면 그것만 전달하는 것도 가능합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > curl -XPUT "http://localhost:9200/my_org/member/1" -H "Content-Type: application/json" -d "{ <span style='color: blue; font-weight: bold'>\"address\": \"dae3jeon KOREA\"</span> }" {"_index":"my_org","_type":"member","_id":"1","_version":2,"result":"updated","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":1,"_primary_term":1} </pre> </span> <br /> 정보를 가져오는 것도 GET 명령어로 가능합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > curl -XGET "http://localhost:9200/my_org/member/1" {"_index":"my_org","_type":"member","_id":"1","_version":1,"found":true,"_source":{ "name" : "tester", "age": 16, "address": "dae3jeon KOREA", "registered":"2017-04-29T10:16:00" }} </pre> <br /> 대충 어떤 식인지 아시겠죠? ^^<br /> <br /> <hr style='width: 50%' /><br /> <br /> elasticsearch가 추론 기능이 있다고는 하지만 당연히 완벽하지 않습니다. 예를 들어, text 타입으로 판정되는 field에 대해서는 색인 작업을 하는 것이 기본 설정입니다. 따라서, "member" 타입의 경우 "name", "address"는 모두 색인 작업을 거치게 됩니다. 그런데, 만약 여기서 "name" 필드가 색인 작업이 필요 없다고 가정해 보겠습니다. 그렇다면 성능을 위해서는 당연히 "name" 필드의 문자열에 대해서는 색인 작업을 하지 않아도 됩니다. 이런 식으로 개발자가 이미 해당 스키마를 잘 알고 있는 경우 최적화된 (type)을 지정해 주는 것이 가능합니다.<br /> <br /> 실습을 위해 이전에 설정한 인덱스(DB)를 삭제해 보겠습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > curl -XDELETE "http://localhost:9200/my_org/" {"acknowledged":true} // 서버 로그 [2018-08-09T09:39:46,322][INFO ][o.e.c.m.MetaDataDeleteIndexService] [Vld1Cby] [my_org/g55350WDSDaHKWMBm9Yi8Q] deleting index </pre> <br /> 자, 다시 처음부터 시작한다고 가정하고 (index)를 먼저 생성합니다. (아래는 기본값으로 index를 생성하는데, 고급 사용자라면 좀 더 사용자 정의할 수 있는 설정들이 있습니다.)<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > curl -XPUT "http://localhost:9200/my_org/" -H "Content-Type: application/json" -d "{ "my_org": { "settings" : { "index" : { } } } }" </pre> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > curl -XPUT "http://localhost:9200/my_org/" -H "Content-Type: application/json" -d "{ \"my_org\": { \"settings\" : { \"index\" : { } } } }" {"acknowledged":true,"shards_acknowledged":true,"index":"my_org"} // 서버 로그 [2018-08-09T10:05:33,163][INFO ][o.e.c.m.MetaDataCreateIndexService] [Vld1Cby] [my_org] creating index, cause [api], templates [], shards [5]/[1], mappings [] </pre> <br /> 그다음 해당 (index)에 소속된 (type)인 member에 대해 스키마를 지정해 줍니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > curl -XPUT "http://localhost:9200/my_org/member/_mapping" -H "Content-Type: application/json" -d "{ "member" : { "properties" : { "name" : {"type" : "text", "index" : "false"}, "age" : {"type" : "integer"}, "address" : {"type" : "text"}, "registered" : {"type" : "date"} } } }" </pre> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > curl -XPUT "http://localhost:9200/my_org/member/_mapping" -H "Content-Type: application/json" -d "{ \"member\" : { \"properties\" : { \"name\" : {\"type\" : \"text\", \"index\" : \"false\"}, \"age\" : {\"type\" : \"integer\"}, \"address\" : {\"type\" : \"text\"}, \"registered\" : {\"type\" : \"date\"} } } }" {"acknowledged":true} // 서버 로그 [2018-08-09T10:20:05,995][INFO ][o.e.c.m.MetaDataMappingService] [Vld1Cby] [my_org/RNr83v64ROSaqqTcvamZoA] create_mapping [member] </pre> <br /> 해당 type이 잘 정의가 되었는지 다음과 같이 확인할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > curl -XGET "http://localhost:9200/my_org/member/_mapping" {"my_org":{"mappings":{"member":{"properties":{"address":{"type":"text"},"age":{"type":"integer"},"name":{"type":"text","index":false},"registered":{"type":"date"}}}}}} // 없는 경우, { "error": { "root_cause": [ { "type":"type_missing_exception", "reason":"type[[member]] missing", "index_uuid":"_na_","index":"_all" } ], "type":"type_missing_exception", "reason":"type[[member]] missing", "index_uuid":"_na_", "index":"_all" }, "status":404 } </pre> <br /> (index)와 (type) 스키마가 생성되었으니, 이제 예전과 똑같이 데이터를 넣어주면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > curl -XPUT "http://localhost:9200/my_org/member/1" -H "Content-Type: application/json" -d "{ "name" : "tester", "age": 16, "address": "daejeon KOREA", "registered":"2017-04-29T10:16:00" }" </pre> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > curl -XPUT "http://localhost:9200/my_org/member/1" -H "Content-Type: application/json" -d "{ \"name\" : \"tester\", \"age\": 16, \"address\": \"daejeon KOREA\", \"registered\":\"2017-04-29T10:16:00\" }" {"_index":"my_org","_type":"member","_id":"1","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":0,"_primary_term":1} </pre> <br /> 참고로, 타입(type)을 삭제하는 것은 불가능합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Delete Mapping ; <a target='tab' href='https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-delete-mapping.html'>https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-delete-mapping.html</a> It is no longer possible to delete the mapping for a type. Instead you should delete the index and recreate it with the new mappings. </pre> <br /> 삭제하려고 했을 때의 반환 메시지는 다음과 같습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > curl -XDELETE "http://localhost:9200/my_org/member/_mapping" { "error":"Incorrect HTTP method for uri [/my_org/member/_mapping] and method [DELETE], allowed: [GET, PUT, POST]", "status":405 } curl -XDELETE "http://localhost:9200/my_org/member" { "error":"Incorrect HTTP method for uri [/my_org/member] and method [DELETE], allowed: [POST]", "status":405 } </pre> <br /> 어차피 index 하나에 type 하나만을 생성할 수 있으므로 type을 지울 의도라면 index를 지우는 걸로 처리할 수 있습니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 마지막으로, 검색 엔진을 설치한 최종 목적인 "검색"을 해봐야 할 것입니다.<br /> <br /> 가령, 주소(address)가 "daejon"을 포함하고 있는 사람을 검색하고 싶다면 다음과 같이 HTTP 쿼리를 날리면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > curl -XGET "http://localhost:9200/my_org/member/_search" -H "Content-Type: application/json" -d "{ "query": { "match": { "address": "daejeon" } } }" </pre> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > curl -XGET "http://localhost:9200/my_org/member/_search" -H "Content-Type: application/json" -d "{ \"query\": { \"match\": { \"address\": \"daejeon\" } } }" {"took":87,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":1,"max_score":0.2876821,"hits":[{"_index":"my_org","_type":"member","_id":"1","_score":0.2876821,"_source":{ "name" : "tester", "age": 16, "address": "daejeon KOREA", "registered":"2017-04-29T10:16:00" }}]}} </pre> <br /> 보는 바와 같이 "hits"의 "total" 속성을 통해 몇 건의 데이터가 검색되었는지 알 수 있습니다. 반면, 검색 결과가 없다면 다음과 같은 응답을 받게 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > curl -XGET "http://localhost:9200/my_org/member/_search" -H "Content-Type: application/json" -d "{ \"query\": { \"match\": { \"address\": \"<span style='color: blue; font-weight: bold'>dae3jeon</span>\" } } }" {"took":9,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}} </pre> <br /> 보다 자세한 검색 옵션은 다음의 글을 참조하세요. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 엘라스틱서치 쿼리 DSL 기초 ; <a target='tab' href='http://bakyeono.net/post/2016-08-20-elasticsearch-querydsl-basic.html'>http://bakyeono.net/post/2016-08-20-elasticsearch-querydsl-basic.html</a> </pre> <br /> 이것으로 전체적인 CRUD 작업을 한 번씩 해봤으니 감이 잡히실 거라고 봅니다. ^^ 생각보다 그다지 어렵지 않죠? 아마도 그래서 더 ElasticSearch가 유명해진 것이 아닌가 싶습니다.<br /> <br /> 이외에, 웹 UI로 ElasticSearch를 편하게 관리할 수 있는 ElasticSearch plug-in이 있습니다. (도움말로 봐서는 Elasticsearch 버전 6 이후는 지원이 안되는 것 같습니다.)<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > ElasticSearch 5.0 Plugin Head 설치 ; <a target='tab' href='http://jjig810906.tistory.com/5'>http://jjig810906.tistory.com/5</a> </pre> <br /> <hr style='width: 50%' /><br /> <br /> (이하의 글은 오류나 시행착오 내용입니다.)<br /> <br /> 제 컴퓨터에 다음과 같은 설정을 했더니,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 영문 설정의 Windows 10 명령행 창(cmd.exe)의 한글 지원 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/11559'>http://www.sysnet.pe.kr/2/0/11559</a> </pre> <br /> elasticsearch.bat 실행 시 다음과 같은 오류가 발생합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 2018-08-09 09:06:00,629 main ERROR Unable to inject fields into builder class for plugin type class org.apache.logging.log4j.core.appender.ConsoleAppender, element Console. java.nio.charset.UnsupportedCharsetException: cp65001 at java.nio.charset.Charset.forName(Charset.java:531) at org.apache.logging.log4j.util.PropertiesUtil.getCharsetProperty(PropertiesUtil.java:146) at org.apache.logging.log4j.util.PropertiesUtil.getCharsetProperty(PropertiesUtil.java:134) at org.apache.logging.log4j.core.appender.ConsoleAppender$Target.getCharset(ConsoleAppender.java:85) at org.apache.logging.log4j.core.appender.ConsoleAppender$Target$1.getDefaultCharset(ConsoleAppender.java:71) ...[생략]... at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:91) at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:84) </pre> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Unable to get Charset 'sun.stdout.encoding', using default UTF-8 java.nio.charset.UnsupportedCharsetException: cp65001 at java.nio.charset.Charset.forName(Charset.java:531) at org.apache.logging.log4j.util.PropertiesUtil.getCharsetProperty(PropertiesUtil.java:172) at org.apache.logging.log4j.core.appender.ConsoleAppender$Target.getCharset(ConsoleAppender.java:89) ...[생략]... at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:93) at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:86) </pre> <br /> 윈도우에서의 65001 지원을 아직 모르는 것 같습니다. ^^ 일단, 다음과 같이 elasticsearch.bat 파일을 수정하는 걸로 임시 조치할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > @echo off <span style='color: blue; font-weight: bold'>chcp 949</span> SET JAVA_HOME=C:\Program Files\Java\jdk1.8.0_161 SETLOCAL enabledelayedexpansion TITLE Elasticsearch 5.4.0 SET params='%*' ...[생략]... </pre> <br /> <hr style='width: 50%' /><br /> <br /> 오픈 소스 쪽 응용 프로그램을 다루다 보면, 마이크로소프트의 "하위 호환성"을 지켜주는 것이 얼마나 대단한 것인지를 알게 되는데요. elasticsearch를 5.x 버전에서 다루다가 6.x로 올렸더니 예전에 작성해 둔 스크립트들을 실행 중에 다음과 같은 오류가 발생했습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > "error": { "root_cause": [ { "type":"mapper_parsing_exception", "reason":"No handler for type [string] declared on field [name]" } ], "type":"mapper_parsing_exception", "reason":"No handler for type [string] declared on field [name]"}, "status":400 }" </pre> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > "error": { "root_cause": [ { "type":"illegal_argument_exception", "reason":"Could not convert [name.index] to boolean" } ], "type":"illegal_argument_exception", "reason":"Could not convert [name.index] to boolean", "caused_by": { "type":"illegal_argument_exception", "reason":"Failed to parse value [not_analyzed] as only [true] or [false] are allowed." } }, "status":400 } </pre> <br /> 물론, 검색하면 다 나옵니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > No handler for type [string] declared on field [name] ; <a target='tab' href='https://stackoverflow.com/questions/47452770/no-handler-for-type-string-declared-on-field-name'>https://stackoverflow.com/questions/47452770/no-handler-for-type-string-declared-on-field-name</a> </pre> <br /> index 지정의 string 타입이 없어졌으니 "text"를 사용하라는 것과, "not_analyzed" 대신 false를 사용하라는 식입니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 하위 호환성이 깨진 것 중 또 하나 의미 있는 것이 있습니다. 본문에서 index == db, type == table이라고 설명했는데요, 그래서 index 하나에 다중 type을 정의할 수 있어 보이지만 이 정책이 ES 버전 6부터 index 하나에 type 하나만을 정의할 수 있도록 바뀌었습니다.<br /> <br /> 그래서 다음과 같이 my_org 인덱스에 member를 생성했다면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > curl -XPUT "http://localhost:9200/my_org/" -H "Content-Type: application/json" -d "{ \"my_org\": { \"settings\" : { \"index\" : { } } } }" curl -XPUT "http://localhost:9200/my_org/member/_mapping" -H "Content-Type: application/json" -d "{ \"member\" : { \"properties\" : { \"name\" : {\"type\" : \"text\", \"index\" : \"false\"}, \"age\" : {\"type\" : \"integer\"}, \"address\" : {\"type\" : \"text\"}, \"registered\" : {\"type\" : \"date\"} } } }" </pre> <br /> 이후, 동일한 인덱스에 다른 type을 생성하려고 하면 다음과 같은 오류가 발생합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > curl -XPUT "http://localhost:9200/my_org/test/_mapping?pretty" -H "Content-Type: application/json" -d "{ \"test\" : { \"properties\" : { \"qwer\" : {\"type\" : \"text\", \"index\" : \"false\"} } } }" { "error" : { "root_cause" : [ { "type" : "illegal_argument_exception", "reason" : "Rejecting mapping update to [my_org] as the final mapping would have more than 1 type: [test, member]" } ], "type" : "illegal_argument_exception", "reason" : "Rejecting mapping update to [my_org] as the final mapping would have more than 1 type: [test, member]" }, "status" : 400 } </pre> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Can't create two Types to same index elasticsearch & Kibana ; <a target='tab' href='https://stackoverflow.com/questions/47632846/cant-create-two-types-to-same-index-elasticsearch-kibana'>https://stackoverflow.com/questions/47632846/cant-create-two-types-to-same-index-elasticsearch-kibana</a> </pre> <br /> 누가 알겠습니까? 향후에는 index, table 따로 정의하던 것을 하나로 합칠지도 모릅니다. 그러다 다시 index 따로 table 따로 정의할 수 있게 만들어 서로 조합할 수 있게 할지도.<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1950
(왼쪽의 숫자를 입력해야 합니다.)