2019년 4월 14일 일요일
2019년 4월 4일 목요일
Elasticsearch - 한번에 데이터를 index로 추가하기 (Bulk Index)
이번에는 한 번에 문서를 Elasticsearch로 2개 이상을 등록하는 방법인 Bulk Index API 예제를 작성한다.
{ "index" : {"_id" : "1" } }
{ "field1": "노코드1", "field2": "노코드2", "field3": "노코드3" }
{ "index" : {"_id" : "2" } }
{ "field1": "노코드1", "field2": "노코드2", "field3": "노코드3" }
위와 같은 파일을 저장한 후 콘솔화면에서 아래의 명령어를 실행한다.
curl -H "Content-Type: application/json" -X POST http://localhost:9200/{index 이름}/{type 이름}/_bulk?pretty --data-binary @bulk.json
bulk.json
{ "index" : {} }
{ "field1": "노코드1", "field2": "노코드2", "field3": "노코드3" }
{ "index" : {} }
{ "field1": "노코드1", "field2": "노코드2", "field3": "노코드3" }
ID를 지정하는 경우
bulk.json{ "index" : {"_id" : "1" } }
{ "field1": "노코드1", "field2": "노코드2", "field3": "노코드3" }
{ "index" : {"_id" : "2" } }
{ "field1": "노코드1", "field2": "노코드2", "field3": "노코드3" }
위와 같은 파일을 저장한 후 콘솔화면에서 아래의 명령어를 실행한다.
curl -H "Content-Type: application/json" -X POST http://localhost:9200/{index 이름}/{type 이름}/_bulk?pretty --data-binary @bulk.json
ID를 지정하지 않는 경우
자동으로 ID가 생성된다.bulk.json
{ "index" : {} }
{ "field1": "노코드1", "field2": "노코드2", "field3": "노코드3" }
{ "index" : {} }
{ "field1": "노코드1", "field2": "노코드2", "field3": "노코드3" }
위와 같은 파일을 저장한 후 콘솔화면에서 아래의 명령어를 실행한다.
curl -H "Content-Type: application/json" -X POST http://localhost:9200/{index 이름}/{type 이름}/_bulk?pretty --data-binary @bulk.json
index / type / id를 json 내에 작성하는 경우
bulk.json
{ "index" : { "_index" : "index 이름", "_type" : "type 이름", "_id" : "1" } }
{ "field1": "노코드1", "field2": "노코드2", "field3": "노코드3" }
위와 같은 파일을 저장한 후 콘솔화면에서 아래의 명령어를 실행한다.
curl -H "Content-Type: application/json" -X POST http://localhost:9200/{index 이름}/{type 이름}/_bulk?pretty --data-binary @bulk.json
2019년 3월 30일 토요일
Elasticsearch 플러그인(Plugin) 만들기
❝Elasticsearch 플러그인❞을 만들기 위해서 여러가지 찾아보고 내용을 정리해본다.
* Elasticsearch 7.x로 업데이트 되면서 BaseRestHandler 인터페이스를 상속받아서 구현하는 방법이 바뀌어서 내용을 업데이트 합니다.
우선 plugin으로 호출되는 클래스 부터 구현한다.
이 plugin으로 호출되는 클래스는
src / main / resources / plugin-descriptor.properties 에 정의한다.
그리고, 위 ExamplePlugin에서 실제로 호출되고 처리를하는 클래스는 ExampleNocodeAction 클래스이다.
구현은 여기까지 하면 완성이다.
이제 mvn install을 실행하여 elasticsearch-example-plugin-7.15.1.zip 플러그인 파일을 생성하자.
마지막으로 Elasticsearch에 elasticsearch-example-plugin-7.15.1.zip plugin을 install 해본다.
./bin/elasticsearch-plugin install file:///elasticsearch/elasticsearch-example-plugin-7.15.1.zip
그리고, 이제 Elasticsearch을 시작한다.
시작 로그에서 다음과 같이
"loaded plugin :[example-plugin]"가 표시되면 성공적으로 install이 된 것이다.
테스트로 플러그인 API를 호출해 본다.
http://localhost:9200/_nocode
* Elasticsearch 7.x로 업데이트 되면서 BaseRestHandler 인터페이스를 상속받아서 구현하는 방법이 바뀌어서 내용을 업데이트 합니다.
환경
- open jdk 11
- maven
- elasticsearch 7.15.1
참고
여기의 코드를 참고함.구현
우선 plugin으로 호출되는 클래스 부터 구현한다.
package org.elasticsearch.plugin.example;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.IndexScopedSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsFilter;
import org.elasticsearch.plugins.ActionPlugin;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestHandler;
public class ExamplePlugin extends Plugin implements ActionPlugin {
@Override
public List<RestHandler> getRestHandlers(final Settings settings,
final RestController restController,
final ClusterSettings clusterSettings,
final IndexScopedSettings indexScopedSettings,
final SettingsFilter settingsFilter,
final IndexNameExpressionResolver indexNameExpressionResolver,
final Supplier<DiscoveryNodes> nodesInCluster) {
return Arrays.asList(
new ExampleNocodeAction(settings, restController));
}
}
이 plugin으로 호출되는 클래스는
src / main / resources / plugin-descriptor.properties 에 정의한다.
version=${project.version} description=${project.description} name=example-plugin classname=org.elasticsearch.plugin.example.ExamplePlugin java.version=11 elasticsearch.version=${elasticsearch.version}
그리고, 위 ExamplePlugin에서 실제로 호출되고 처리를하는 클래스는 ExampleNocodeAction 클래스이다.
package org.elasticsearch.plugin.example;
import static org.elasticsearch.rest.RestRequest.Method.GET;
import static org.elasticsearch.rest.RestStatus.OK;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.BytesRestResponse;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest;
/**
* Example action with a plugin.
*/
public class ExampleNocodeAction extends BaseRestHandler {
public ExampleNocodeAction(final Settings settings,
final RestController controller) {
// nothing
}
@Override
public String getName() {
return "nocode_example_action.";
}
@Override
public List<Route> routes() {
return Collections.unmodifiableList(Arrays.asList(
new Route(GET, "/{index}/_nocode"),
new Route(GET, "/_nocode")));
}
@Override
protected RestChannelConsumer prepareRequest(final RestRequest request,
final NodeClient client) throws IOException {
final boolean isPretty = request.hasParam("pretty");
final String index = request.param("index");
return channel -> {
final XContentBuilder builder = JsonXContent.contentBuilder();
if (isPretty) {
builder.prettyPrint().lfAtEnd();
}
builder.startObject();
if (index != null) {
builder.field("index", index);
}
builder.field("description",
"This is a example response: " + new Date().toString());
builder.endObject();
channel.sendResponse(new BytesRestResponse(OK, builder));
};
}
}
구현은 여기까지 하면 완성이다.
이제 mvn install을 실행하여 elasticsearch-example-plugin-7.15.1.zip 플러그인 파일을 생성하자.
마지막으로 Elasticsearch에 elasticsearch-example-plugin-7.15.1.zip plugin을 install 해본다.
./bin/elasticsearch-plugin install file:///elasticsearch/elasticsearch-example-plugin-7.15.1.zip
그리고, 이제 Elasticsearch을 시작한다.
시작 로그에서 다음과 같이
"loaded plugin :[example-plugin]"가 표시되면 성공적으로 install이 된 것이다.
[2021-10-15T08:16:36,445][INFO ][o.e.p.PluginsService ] [local] loaded module [x-pack-watcher] [2021-10-15T08:16:36,445][INFO ][o.e.p.PluginsService ] [local] loaded plugin [example-plugin] [2021-10-15T08:16:36,482][INFO ][o.e.e.NodeEnvironment ] [local] using [1] data paths, mounts [[/ (/dev/disk1s1)]], net usable_space [35gb], net total_space [233.4gb], types [apfs] [2021-10-15T08:16:36,482][INFO ][o.e.e.NodeEnvironment ] [local] heap size [989.8mb], compressed ordinary object pointers [true] [2021-10-15T08:16:36,555][INFO ][o.e.n.Node ] [local] node name [local], node ID [6pG_WeHkSEKR3FLLjResXg], cluster name [elasticsearch], roles [transform, data_frozen, master, remote_cluster_client, data, ml, data_content, data_hot, data_warm, data_cold, ingest] [2021-10-15T08:16:40,472][INFO ][o.e.x.m.p.l.CppLogMessageHandler] [local] [controller/67091] [Main.cc@122] controller (64 bit): Version 7.15.1 (Build 96c59930f1bbe9) Copyright (c) 2021 Elasticsearch BV
http://localhost:9200/_nocode
2019년 3월 28일 목요일
Elasticsearch - 자주 사용하는 명령어(CMD) 목록
검색 운영 업무중에 자주 사용하는 명령어(CMD) 목록을 정리해 본다.
목록
- Elasticsearch 관련
- Index 관련
- Alias 관련
- Document 유형 관련
- ReIndex API
1. Elasticsearch 관련
시작sudo /etc/init.d/elasticsearch start
재시작
sudo /etc/init.d/elasticsearch restart
상태확인
curl -XGET 'localhost:9200/'
2. Index 관련
인덱스 확인
curl -XGET 'localhost:9200/_cat/indices?v'
설정 확인
curl -XGET 'localhost:9200/{indexName}/_settings?pretty'
맵핑 확인
curl -XGET 'localhost:9200/{indexName}/_mapping?pretty'
삭제
curl -XDELETE 'localhost:9200/{indexName}?pretty'
3. Alias 관련
Alias 확인
curl -XGET 'localhost:9200/_aliases?pretty'
4. Document 관련
문서 수 확인
curl -sS -XGET 'localhost:9200/{indexName}/{typeName}/_count?pretty'
필드추가
curl -XPUT 'localhost:9200/{indexName}/_mappings/{typeName}?pretty' -d '
{
"properties" : {
"field1" : {
"type" : "long"
},
"field2" : {
"type" : "date"
}
}
}'
벌크색인
curl -XPOST 'localhost:9200/{indexName}/{typeName}/_bulk?pretty' --data-binary @xxx.json
전체 데이터 삭제
curl -XPOST 'localhost:9200/{indexName}/{typeName}/_delete_by_query' --d '
{
"query":{
"match_all":{
}
}
}'
데이터 검색
curl -sS -XGET 'localhost:9200/{indexName}/{typeName}/_search?pretty'
데이터 검색 ((From-To 지정)
curl -sS -XGET 'localhost:9200/{indexName}/{typeName}/_search?pretty' -d '
{
"query":{
"match_all":{
}
},
"from":0,
"size":400
}'
데이터 갱신 (ID 지정)
curl -XPOST 'localhost:9200/{indexName}/{typeName}/{id}/_update' -d '
{
"doc":{
"field1": "test123"
}
}'
데이터 일괄 업데이트
curl -XPOST 'localhost:9200/{indexName}/{typeName}/_update_by_query?conflicts=proceed&pretty' -d '
{
"query":{
"match_all": { }
},
"script":{
"inline": "ctx._source.field1 = 'test123'"
}
}'
5. ReIndex API
reindex
curl -XPOST 'localhost:9200/_reindex?pretty' -d '
{
"source": {
"index": "fromIndex"
},
"dest": {
"index": "toIndex"
}
}'
reindex (remote)
curl -XPOST 'localhost:9200/_reindex?pretty' -d '
{
"source": {
"remote": {
"host": "http://otherhost:9200",
"username": "user",
"password": "pass"
},
"index": "fromIndex"
}
},
"dest": {
"index": "toIndex"
}
}
Elasticsearch와 Kibana 학습에 필요한 정보
VIDEO
https://www.elastic.co/kr/videos/참고도서
영문 원서로 보기를 추천 : 번역서 - 일래스틱 스택 6 입문 (에이콘출판사) 은 한글 번역을 해석하기가 더 어렵다. :(
슬라이드
Elastic Search (엘라스틱서치) 입문
https://www.slideshare.net/seunghyuneom/elastic-search-52724188
엘라스틱서치 이해하기
https://www.slideshare.net/dahlmoon/20160613
형태소분석기를 적용한 엘라스틱서치 운영
https://speakerdeck.com/seapy/hyeongtaeso-bunseoggireul-jeogyonghan-elasticsearch-unyeong
Amazon elasticsearch 서비스 소개 및 활용 방법
https://www.slideshare.net/awskorea/amazon-elasticsearch-service-58642601
https://speakerdeck.com/seapy/hyeongtaeso-bunseoggireul-jeogyonghan-elasticsearch-unyeong
Amazon elasticsearch 서비스 소개 및 활용 방법
https://www.slideshare.net/awskorea/amazon-elasticsearch-service-58642601
2015년 9월 9일 수요일
Elasticsearch 2.0.0-beta1 릴리즈 (번역)
※ 이 글은 Elasticsearch 블로그를 번역 한 것입니다.
원문 : Elasticsearch 2.0.0-beta1 released
오늘 (8/26), Lucene 5.2.1 기반 Elasticsearch 2.0.0-beta1 을 출시했습니다. 본 자료는 469 명의 커미터에서 2,500 개 이상의 pull request를 포함하고 있습니다. pull request 중 약 850가 2.0을위한 새로운 것입니다.
주의 사항 본 보도 자료는 베타 버전이며, 테스트를 목적으로 한 것입니다. Elasticsearch 2.0.0-beta1은 Elasticsearch 2.0.0 GA와 호환 여부를 보증하지 않습니다.
프로덕션 환경에는 사용하지 마십시오.
Elasticsearch 2.0.0-beta1 다운로드 및 모든 변경 내용은 링크 를 참조하십시오.
Elasticsearch 2.0.0-beta1에는 다음의 새로운 변경 사항이 포함되어 있습니다.
위의 변경 이외에도 많은 Elasticsearch와 Lucene에 대한 지속적인 변경 사항이 포함되어 있습니다. 이들은 Elasticsearch 2.0를 더 안전하게, 더 쉽게, 더 좋은 것으로하고 있습니다. 릴리스에 대한 더 자세한 정보를 다음 블로그에 있으므로 참고하십시오.
또한 Elasticsearch 2.0.0-beta1의 문서 를 참조 할 수도 있습니다. 특히 2.0의 주요 변경 사항 은 반드시 읽어주십시오.
sudo bin/plugin install analysis-icu
플러그인 새 문서 는 우리의 Web 사이트 Guide 에 있습니다.
sudo bin / plugin install license
sudo bin / plugin install shield
sudo bin / plugin install watcher
Marvel 및 Sense에 대한 새로운 정보도 있지만, 조금만 더 기다려주십시오.
2.0.0-beta1 상용 플러그인에 관한 문서는 다음 링크를 클릭하십시오.
이 플러그인의 이용 방법은 Elasticsearch Migration repository 를 참조하십시오.
꼭 Elasticsearch 2.0.0-beta1 을 다운로드하여 사용해보십시오. 그리고 감상을 Twitter ( @elastic )와 포럼 등에서 가르쳐주세요. 문제가 있으시면 GitHub issues page 에서 보고를 부탁합니다.
원문 : Elasticsearch 2.0.0-beta1 released
오늘 (8/26), Lucene 5.2.1 기반 Elasticsearch 2.0.0-beta1 을 출시했습니다. 본 자료는 469 명의 커미터에서 2,500 개 이상의 pull request를 포함하고 있습니다. pull request 중 약 850가 2.0을위한 새로운 것입니다.
주의 사항 본 보도 자료는 베타 버전이며, 테스트를 목적으로 한 것입니다. Elasticsearch 2.0.0-beta1은 Elasticsearch 2.0.0 GA와 호환 여부를 보증하지 않습니다.
프로덕션 환경에는 사용하지 마십시오.
Elasticsearch 2.0.0-beta1 다운로드 및 모든 변경 내용은 링크 를 참조하십시오.
Elasticsearch 2.0.0-beta1에는 다음의 새로운 변경 사항이 포함되어 있습니다.
- Pipeline Aggregations : 이것은 다른 aggregations 결과에 대한 Aggregation을 수행 할 수 있습니다. (도함수 이동 평균, Holt Winter 예측 알고리즘 등 포함)
- 디스크 및 파일 시스템 캐시에 더 적합한 더 나은 데이터 압축
- doc-values가 기본이 된 것,병합 실행시 메모리 사용량 감소,필터 캐시를위한 roaring bitsets 등으로 더 효율적인 힙 사용율
- 구조화 된 예외
- 최적화 된 쿼리 실행 순서 필터 자동 캐시 빠른 쿼리에 재 작성된 parent-child
- 설정 대신 피드백 루프를 사용하여 자동 조정
- 트랜잭션 로그에 쓰기가 기본적으로 원자이고 중복
- 안전하고 명확하고 신뢰할 수있는 타입 매핑
- 기본적으로 로컬 호스트에서만 클러스터를 구성
- 클러스터 상태의 차이에 의해 더 빠르게 변경을 전파
위의 변경 이외에도 많은 Elasticsearch와 Lucene에 대한 지속적인 변경 사항이 포함되어 있습니다. 이들은 Elasticsearch 2.0를 더 안전하게, 더 쉽게, 더 좋은 것으로하고 있습니다. 릴리스에 대한 더 자세한 정보를 다음 블로그에 있으므로 참고하십시오.
- Elasticsearch 2.0.0.beta1 coming soon!
- The Great Mapping Refactoring
- Store compression in Lucene and Elasticsearch
- Better query execution coming to Elasticsearch 2.0
- Out of this world aggregations
- Staying in Control with Moving Averages - Part 1
- Staying in Control with Moving Averages - Part 2
- The Delete by Query API Is now a plugin
- Elasticsearch unplugged - Networking changes in 2.0
또한 Elasticsearch 2.0.0-beta1의 문서 를 참조 할 수도 있습니다. 특히 2.0의 주요 변경 사항 은 반드시 읽어주십시오.
Core plugins
코어 플러그인 개발 방법을 변경했습니다. 공식적으로 지원하는 플러그인은 현재 elasticsearch 저장소 에 포함되어 있습니다. 이는 코어와 함께 테스트되고 Elasticsearch와 같은시기에 출시됩니다. 코어 플러그인은 Elasticsearch와 같은 버전 번호입니다. 설치는 다음과 같이 합니다.sudo bin/plugin install analysis-icu
플러그인 새 문서 는 우리의 Web 사이트 Guide 에 있습니다.
Commercial plugins
우리의 상용 플러그인도 Elasticsearch와 같은 버전 번호가 되어 Elasticsearch와 함께 출시됩니다. Shield 및 Watcher는 이미 2.0.0-beta1이 가능합니다. 설치를위한 명령은 다음과 같습니다.sudo bin / plugin install license
sudo bin / plugin install shield
sudo bin / plugin install watcher
Marvel 및 Sense에 대한 새로운 정보도 있지만, 조금만 더 기다려주십시오.
2.0.0-beta1 상용 플러그인에 관한 문서는 다음 링크를 클릭하십시오.
Elasticsearch Migration plugin
Elasticsearch 2.0.0-beta1을 시도하기 전에 기존 인덱스 업그레이드하기 위해 무엇인가 할 필요가 있는지 여부를 확인하기 위한 Elasticsearch Migration Plugin도 발표했다. 2.0.0에서 동작하지 않는 문제가 있는지 매핑 등을 찾을 수있는 유용한 플러그인입니다.이 플러그인의 이용 방법은 Elasticsearch Migration repository 를 참조하십시오.
알려진 이슈
같은 인덱스의 종류에 같은 이름의 ip 타입의 필드를 추가 할 때 문제가 있는 것을 알 수 있습니다. 이 문제는 다음 버전에서 수정됩니다. 자세한 내용은 # 13112 을 참조하십시오.테스트합시다!
Elasticsearch 2.0.0 GA를 신속하게 출시 할 수 있도록 더 많은 베타 테스터를 기다리고 있습니다.꼭 Elasticsearch 2.0.0-beta1 을 다운로드하여 사용해보십시오. 그리고 감상을 Twitter ( @elastic )와 포럼 등에서 가르쳐주세요. 문제가 있으시면 GitHub issues page 에서 보고를 부탁합니다.
2015년 8월 28일 금요일
Elasticsearch를 사용하여 게시판의 첨부파일 내용 검색하기
이번에는 홈페이지 또는 기업에서 많이 사용되는 게시판의 제목과 본문 그리고 첨부된 문서의 텍스트를 검색하는 단계를 정리한다.
pdf 또는 ms-office 문서에서 텍스트 추출을 하기 위한 플러그인
문서파일은 아파치 Tika가 동작해서 attachment 유형을 사용할 수있게 해준다.
bin/plugin -install elasticsearch/elasticsearch-mapper-attachments/2.7.0
설치확인
curl -XGET http://localhost:9200/_nodes?pretty
설치 참고) Elasticsearch에 한국어 형태소분석기 Mecab ko 적용
PUT /test
{
"settings" : {
"index":{
"analysis":{
"filter" : {
"synonym" : {
"type" : "synonym",
"synonyms_path" : "analysis/synonyms.txt"
}
},
"analyzer":{
"korean":{
"filter" : [
"standard",
"lowercase",
"stop",
"synonym"
],
"type":"custom",
"tokenizer":"mecab_ko_standard_tokenizer"
}
},
"tokenizer": {
"mecab_ko_standard_tokenizer": {
"type": "mecab_ko_standard_tokenizer",
"mecab_args": "-d /home/elasticsearch/knowledge/mecab/dic/mecab-ko-dic"
}
}
}
}
},
"mappings": {
"board" : {
"properties": {
"title": {
"type": "string",
"analyzer": "korean"
},
"content": {
"type": "string",
"analyzer": "korean"
},
"file": {
"type": "attachment",
"fields" : { "file" : { "term_vector":"with_positions_offsets", "store":"yes” } },
"analyzer": "korean"
}
}
}
}
}
수동 입력의 예)
POST /test/board/1
{
"id": "1",
"title" : “「2015~2016년 해외 한국자료실 설치 지원 사업」수요조사 신청 안내",
"content" : "대한민국 국립중앙도서관에서는 「2015~2016 해외 한국자료실 설치 지원 사업 : Window On Korea(WOK)」을 위한 수요조사를 실시하오니, 관심 있는 기관들의 많은 참여 바랍니다. 한국자료실 설치를 희망하는 기관은 “수요조사 신청서“를 작성하여, e-mail 또는 fax로 제출하여 주시기 바랍니다. ㅇ 2015년도 설치사업 : 2015년 5월 15일(금)까지 ㅇ 2016년도 설치사업 : 2015년 10월 30일(금)까지",
"filePath": "/data1/attach/doc/1.docx",
"file": "",
"filterYn": "N",
"createDate": "2015-08-28T12:00:00"
}
문서파일 업데이트 데몬을 통해 해당 Index의 문서중에 filterYn값이 N인 파일을 BASE64인코딩해서 업데이트한다.
문서파일 색인 업데이트 프로세스
4.1 filterYn에서 N인 조건 + filePath가 empty가 아닌 문서 가져오기
검색조건
GET /test/board/_search
{
"fields": ["id", "filePath"]
,"query": {
"filtered": {
"filter":
{
"bool": {
"must": {"term": { "filterYn": “n" }},
"must_not": {"term": {"filePath": ""}}
}
}
}
}
}
4.2 문서결과는 id와 filePath만 전달 받는다.
{
"took": 14,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "test",
"_type": "board",
"_id": "1",
"_score": 1,
"fields": {
"id": [
"1"
],
"filePath": [
"/data1/attach/doc/1.docx"
]
}
}
]
}
}
4.3 filePath 필드의 문서는 바이너리 데이터를 BASE64로 인코딩한다.
- 바이너리 파일을 읽어서 BASE64로 반환하는 JAVA Class
https://gist.github.com/utkarsh2012/1276960
4.4 Elasticsearch에 문서를 업데이트 요청한다. 데몬에서 Elasticsearch로 전달하는 URL
CURL로 업데이트할 경우의 예)
curl -XPOST “localhost:9200/test/board/1/_update" -d '
{
“doc” :
{
“id”: “1”,
“filterYn”: “Y”,
“file” : “ base64 encoding string …."
}
}
GET /test/board/_search
{
"fields": ["id", "title", "content"]
,"query": {
"bool": {
"must": [
{
"multi_match": {
"query": “설치사업",
"fields": [
"content^10",
"title^100",
"file"
],
"type": "cross_fields",
"operator":"AND",
"minimum_should_match": "75%"
}
}
]
}
},
"highlight": {
"fields": {"file": {"fragment_size" : 150, "number_of_fragments" : 3}}
}
}
- Elasticsearch 버전 1.7.1
- Elastic search mapper attachment 버전 2.7.0
1. 필요한 플러그인 설치
Mapper Attachments Type for Elasticsearchpdf 또는 ms-office 문서에서 텍스트 추출을 하기 위한 플러그인
문서파일은 아파치 Tika가 동작해서 attachment 유형을 사용할 수있게 해준다.
bin/plugin -install elasticsearch/elasticsearch-mapper-attachments/2.7.0
설치확인
curl -XGET http://localhost:9200/_nodes?pretty
2. 인덱스 매핑 정의
인덱스 매핑은 한국어 형태소분석을 사용하도록 설정한다.설치 참고) Elasticsearch에 한국어 형태소분석기 Mecab ko 적용
PUT /test
{
"settings" : {
"index":{
"analysis":{
"filter" : {
"synonym" : {
"type" : "synonym",
"synonyms_path" : "analysis/synonyms.txt"
}
},
"analyzer":{
"korean":{
"filter" : [
"standard",
"lowercase",
"stop",
"synonym"
],
"type":"custom",
"tokenizer":"mecab_ko_standard_tokenizer"
}
},
"tokenizer": {
"mecab_ko_standard_tokenizer": {
"type": "mecab_ko_standard_tokenizer",
"mecab_args": "-d /home/elasticsearch/knowledge/mecab/dic/mecab-ko-dic"
}
}
}
}
},
"mappings": {
"board" : {
"properties": {
"title": {
"type": "string",
"analyzer": "korean"
},
"content": {
"type": "string",
"analyzer": "korean"
},
"file": {
"type": "attachment",
"fields" : { "file" : { "term_vector":"with_positions_offsets", "store":"yes” } },
"analyzer": "korean"
}
}
}
}
}
3. JDBC River를 사용해서 DB데이터 id, title, content, filePath, filterYn, createDate를 색인
JDBC River 사용하기수동 입력의 예)
POST /test/board/1
{
"id": "1",
"title" : “「2015~2016년 해외 한국자료실 설치 지원 사업」수요조사 신청 안내",
"content" : "대한민국 국립중앙도서관에서는 「2015~2016 해외 한국자료실 설치 지원 사업 : Window On Korea(WOK)」을 위한 수요조사를 실시하오니, 관심 있는 기관들의 많은 참여 바랍니다. 한국자료실 설치를 희망하는 기관은 “수요조사 신청서“를 작성하여, e-mail 또는 fax로 제출하여 주시기 바랍니다. ㅇ 2015년도 설치사업 : 2015년 5월 15일(금)까지 ㅇ 2016년도 설치사업 : 2015년 10월 30일(금)까지",
"filePath": "/data1/attach/doc/1.docx",
"file": "",
"filterYn": "N",
"createDate": "2015-08-28T12:00:00"
}
4. 첨부파일이 저장되어 있는 서버에서 Elasticsearch로 첨부파일 색인 요청을 한다.
문서파일 업데이트 데몬을 통해 해당 Index의 문서중에 filterYn값이 N인 파일을 BASE64인코딩해서 업데이트한다.
문서파일 색인 업데이트 프로세스
4.1 filterYn에서 N인 조건 + filePath가 empty가 아닌 문서 가져오기
검색조건
GET /test/board/_search
{
"fields": ["id", "filePath"]
,"query": {
"filtered": {
"filter":
{
"bool": {
"must": {"term": { "filterYn": “n" }},
"must_not": {"term": {"filePath": ""}}
}
}
}
}
}
4.2 문서결과는 id와 filePath만 전달 받는다.
{
"took": 14,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "test",
"_type": "board",
"_id": "1",
"_score": 1,
"fields": {
"id": [
"1"
],
"filePath": [
"/data1/attach/doc/1.docx"
]
}
}
]
}
}
4.3 filePath 필드의 문서는 바이너리 데이터를 BASE64로 인코딩한다.
- 바이너리 파일을 읽어서 BASE64로 반환하는 JAVA Class
https://gist.github.com/utkarsh2012/1276960
4.4 Elasticsearch에 문서를 업데이트 요청한다. 데몬에서 Elasticsearch로 전달하는 URL
CURL로 업데이트할 경우의 예)
curl -XPOST “localhost:9200/test/board/1/_update" -d '
{
“doc” :
{
“id”: “1”,
“filterYn”: “Y”,
“file” : “ base64 encoding string …."
}
}
5. 검색 결과 확인하기
GET /test/board/_search
{
"fields": ["id", "title", "content"]
,"query": {
"bool": {
"must": [
{
"multi_match": {
"query": “설치사업",
"fields": [
"content^10",
"title^100",
"file"
],
"type": "cross_fields",
"operator":"AND",
"minimum_should_match": "75%"
}
}
]
}
},
"highlight": {
"fields": {"file": {"fragment_size" : 150, "number_of_fragments" : 3}}
}
}
2015년 8월 25일 화요일
Elasticsearch에서 Mecab Ko 사전경로 변경하기
Elasticsearch Settings > Analysis > Analyzer, Tokenizer를 Mecab Ko로 설정한다.
Index analysis는 Analyzer, Tokenizer, TokenFilter로 구성된다.
1. Analysis 설정 구조
index :
analysis :
analyzer :
standard :
type : standard
stopwords : [stop, stop2]
myAnalyzer :
type : standard
stopwords : [stop1, stop2, stop3]
max_token_length : 500
tokenizer :
myTokenizer :
type : standard
max_token_length : 900
filter :
myTokenFilter :
type : stop
stopwords : [stop1, stop2, stop3, stop4]
* max_token_length의 기본값은 255이다.
2. Mecab Ko Analysis 설정
setting에서 아래와 같이 사전경로 지정을 위해 tokenizer > mecab_args를 추가한다.
PUT /shop
{
"settings" : {
"index":{
"analysis":{
"analyzer":{
"korean":{
"type":"custom",
"tokenizer":"mecab_ko_standard_tokenizer"
}
},
"tokenizer": {
"mecab_ko_standard_tokenizer": {
"type": "mecab_ko_standard_tokenizer",
"mecab_args": "-d /home/elasticsearch/knowledge/mecab/dic/mecab-ko-dic"
}
}
}
}
}
}
[분석 결과보기]
GET /shop/_analyze?analyzer=korean&pretty=true
{
레노버노트북
}
[참고 URL]
Elasticsearch에서 Mecab Ko 동의어사전 적용하기
Elasticsearch Settings > Analysis > Filter 설정
Index analysis는 Analyzer, Tokenizer, TokenFilter로 구성된다.
TOKEN FILTER 종류
33개
tokenizer로 부터 token stream을 받아서 token에 대해 lower case, add, delete 등을 처리
Synonym Token Filter
동의어를 적용하는 필터. Elasticsearch에 포함되어 있다.
# 설정 예제
PUT /shop
{
"settings" : {
"index":{
"analysis":{
"filter" : {
"synonym" : {
"type" : "synonym",
"synonyms_path" : "analysis/synonyms.txt"
}
},
"analyzer":{
"korean":{
"filter" : [
"standard",
"lowercase",
"stop",
"synonym"
],
"type":"custom",
"tokenizer":"mecab_ko_standard_tokenizer"
}
},
"tokenizer": {
"mecab_ko_standard_tokenizer": {
"type": "mecab_ko_standard_tokenizer",
"mecab_args": "-d /home/elasticsearch/knowledge/mecab/dic/mecab-ko-dic"
}
}
}
}
}
}
# edit : $ES_HOME/config/analysis/synonym.txt
노트북,labtop,notebook
# 확인 명령
$ curl -XGET ‘localhost:9200/shop/_analyze?analyzer=korean&pretty=true' -d ‘노트북'
# 노트북 labtop notebook
Elasticsearch Analysis (by Elasticsearch Korea)
Elasticsearch에 Mecab Ko 사전경로 설정하는 방법을 설명하기 전에 Analysis 개념을 먼저 정리한다.
본 내용은 Elasticsearch Korea의 Youngsik Yun님 발표자료를 옮긴 것입니다.
(* 원문: http://elasticsearch-kr.github.io/presentations/2014-04-30-analysis/#/)
Index analysis는 Analyzer, Tokenizer, TokenFilter로 구성되면 Terms 인덱스를 만든다.
Character Filtering: Turns the input string into a different string (Pre-processes)
Tokenization: Divide the char-filtered string into an array of tokens
Token Filtering: Post-processes the filtered tokens into a mutated token array
default analyzer : 8종류
or
custom analyzer 작성
3.1 DEFAULT ANALYZER
standard
simple
whitespace
stop
keyword
pattern
language
snowball
1) STANDARD ANALYZER
standard Tokenizer
+ standard TokenFilter
+ lowercase TokenFilter
+ stop TokenFilter
언제 사용? 지정 한하면 기본 적용되는 analzyer이다
2) SIMPLE ANALYZER
only lower case tokenizer 만 구성
3) WHITESPACE ANALYZER
whitespace tokenizer 만 구성
4) STOP ANALYZER
lower case tokenizer
+
stop token filter
언제 사용? stopwords 를 등록한다
5) KEYWROD ANALYZER
not_analyzed로 마킹 (이해불가)
6) PATTENRN ANALYZER
regular expression을 통해서 텍스트 분류
lowercase + pattern + flags + stopwords 옵션
7) LANGUAGE ANALYZER
지정한 단어가 나오면 analyzing 하는 목적
8) SNOWBALL ANALYZER
standard tokenizer
+ standard filter, lowercase filter
+ stop filter, snowball filter
언제 사용? streaming 분석기
3.2 CUSTOM ANALYZER
Tokenizer
+ Token Filter (zero or more)
+ Char Filters (zero or more)
standard
edge ngram
keyword
letter
lowercase
ngram
whitespace
pattern
uax email url
path heirarchy
1) STANDARD TOKENIZER
Unicode Text Segment Algorithm
basic grammer tokenizer
max_token_length (default 255)
길이 넘으면 무시
2) EDGE NGRAM TOKENIZER
nGram 과 유사
"tokenizer" : {
"my_edge_ngram_tokenizer" : {
"type" : "edgeNGram",
"min_gram" : "2",
"max_gram" : "5",
"token_chars": [ "letter", "digit" ]
}
}
3) KEYWORD TOKENIZER
Keyword
buffer_size 256
4) WHITESPACE TOKENIZER
text를 whitespace 별로 나눈다
5) LETTER TOKENIZER
text에서 letter 아닌 것 제거
6) LOWERCASE TOKENIZER
letter tokenizer + lowercase tokenfilter
즉, letter가 아닌 것 제거하고 lower case 로 만듦
7) NGRAM TOKENIZER
"tokenizer" : {
"my_ngram_tokenizer" : {
"type" : "nGram",
"min_gram" : "2",
"max_gram" : "3",
"token_chars": [ "letter", "digit" ]
}
}
8) PATTERN TOKENIZER
regular expression 사용
pattern + flags + group 옵션
9) UAZ EMAIL URL TOKENIZER
standard tokenizer 같고 email, url 나누기
max_token_length (default 255)
10) PATH HIERARCHY TOKENIZER
path 나누기
/something/something/else
And produces tokens:
/something
/something/something
/something/something/else
옵션
delimiter (default /)
replacement (option, delimiter 나오면 대체)
buffer_size (default 1024)
reverse (default false)
skip (처음 건너뛰기, default 0)
33개
tokenizer로 부터 token stream을 받아서 token에 대해 lower case, add, delete 등을 처리
1) STANDARD TOKEN FILTER
normalize token
2) ASCII FOLDING TOKEN FILTER
알파벳, 숫자, 기호를 ascii 로 변환
"index" : {
"analysis" : {
"analyzer" : {
"default" : {
"tokenizer" : "standard",
"filter" : ["standard", "asciifolding"]
}
}
}
}
이렇게 FILTER를 표현
"index" : {
"analysis" : {
"analyzer" : {
"default" : {
"tokenizer" : "standard",
"filter" : ["standard", "my_ascii_folding"]
}
},
"filter" : {
"my_ascii_folding" : {
"type" : "asciifolding",
"preserve_original" : true
}
}
}
}
3) LENGTH TOKEN FILTER
min~max 주어서 remove word
4) LOWERCASE TOKEN FILTER
5) UPPERCASE TOKEN FILTER
6) NGRAM TOKEN FILTER
min_gram ~ max_gram
7) EDGE NGRAM TOKEN FILTER
그외 ...
Tokenizer를 통과하기 전에 string에 대한 전처리기
3개
mapping
html strip
pattern replace
1) MAPPING CHAR FILTER
맵핑 설정한 문자로 바꾸어 준다
{
"index" : {
"analysis" : {
"char_filter" : {
"my_mapping" : {
"type" : "mapping",
"mappings" : ["ph=>f", "qu=>q"]
}
},
"analyzer" : {
"custom_with_char_filter" : {
"tokenizer" : "standard",
"char_filter" : ["my_mapping"]
},
}
}
}
}
2) HTML STRIP CHAR FILTER
html strip
3) PATTERN REPLACE CHAR FILTER
regex
ICU? International Components for Unicode
종류
icu_normalization
icu_folding
filtering
icu_collation
본 내용은 Elasticsearch Korea의 Youngsik Yun님 발표자료를 옮긴 것입니다.
(* 원문: http://elasticsearch-kr.github.io/presentations/2014-04-30-analysis/#/)
1. Analysis개념
Index analysis는 Analyzer, Tokenizer, TokenFilter로 구성되면 Terms 인덱스를 만든다.
2. Analyzer 구성요소
Character Filtering: Turns the input string into a different string (Pre-processes)
Tokenization: Divide the char-filtered string into an array of tokens
Token Filtering: Post-processes the filtered tokens into a mutated token array
3. ANALYZER 종류
default analyzer : 8종류
or
custom analyzer 작성
3.1 DEFAULT ANALYZER
standard
simple
whitespace
stop
keyword
pattern
language
snowball
1) STANDARD ANALYZER
standard Tokenizer
+ standard TokenFilter
+ lowercase TokenFilter
+ stop TokenFilter
언제 사용? 지정 한하면 기본 적용되는 analzyer이다
2) SIMPLE ANALYZER
only lower case tokenizer 만 구성
3) WHITESPACE ANALYZER
whitespace tokenizer 만 구성
4) STOP ANALYZER
lower case tokenizer
+
stop token filter
언제 사용? stopwords 를 등록한다
5) KEYWROD ANALYZER
not_analyzed로 마킹 (이해불가)
6) PATTENRN ANALYZER
regular expression을 통해서 텍스트 분류
lowercase + pattern + flags + stopwords 옵션
7) LANGUAGE ANALYZER
지정한 단어가 나오면 analyzing 하는 목적
8) SNOWBALL ANALYZER
standard tokenizer
+ standard filter, lowercase filter
+ stop filter, snowball filter
언제 사용? streaming 분석기
3.2 CUSTOM ANALYZER
Tokenizer
+ Token Filter (zero or more)
+ Char Filters (zero or more)
4. TOKENIZER 종류
10개standard
edge ngram
keyword
letter
lowercase
ngram
whitespace
pattern
uax email url
path heirarchy
1) STANDARD TOKENIZER
Unicode Text Segment Algorithm
basic grammer tokenizer
max_token_length (default 255)
길이 넘으면 무시
2) EDGE NGRAM TOKENIZER
nGram 과 유사
"tokenizer" : {
"my_edge_ngram_tokenizer" : {
"type" : "edgeNGram",
"min_gram" : "2",
"max_gram" : "5",
"token_chars": [ "letter", "digit" ]
}
}
3) KEYWORD TOKENIZER
Keyword
buffer_size 256
4) WHITESPACE TOKENIZER
text를 whitespace 별로 나눈다
5) LETTER TOKENIZER
text에서 letter 아닌 것 제거
6) LOWERCASE TOKENIZER
letter tokenizer + lowercase tokenfilter
즉, letter가 아닌 것 제거하고 lower case 로 만듦
7) NGRAM TOKENIZER
"tokenizer" : {
"my_ngram_tokenizer" : {
"type" : "nGram",
"min_gram" : "2",
"max_gram" : "3",
"token_chars": [ "letter", "digit" ]
}
}
8) PATTERN TOKENIZER
regular expression 사용
pattern + flags + group 옵션
9) UAZ EMAIL URL TOKENIZER
standard tokenizer 같고 email, url 나누기
max_token_length (default 255)
10) PATH HIERARCHY TOKENIZER
path 나누기
/something/something/else
And produces tokens:
/something
/something/something
/something/something/else
옵션
delimiter (default /)
replacement (option, delimiter 나오면 대체)
buffer_size (default 1024)
reverse (default false)
skip (처음 건너뛰기, default 0)
5. TOKEN FILTER 종류
33개
tokenizer로 부터 token stream을 받아서 token에 대해 lower case, add, delete 등을 처리
1) STANDARD TOKEN FILTER
normalize token
2) ASCII FOLDING TOKEN FILTER
알파벳, 숫자, 기호를 ascii 로 변환
"index" : {
"analysis" : {
"analyzer" : {
"default" : {
"tokenizer" : "standard",
"filter" : ["standard", "asciifolding"]
}
}
}
}
이렇게 FILTER를 표현
"index" : {
"analysis" : {
"analyzer" : {
"default" : {
"tokenizer" : "standard",
"filter" : ["standard", "my_ascii_folding"]
}
},
"filter" : {
"my_ascii_folding" : {
"type" : "asciifolding",
"preserve_original" : true
}
}
}
}
3) LENGTH TOKEN FILTER
min~max 주어서 remove word
4) LOWERCASE TOKEN FILTER
5) UPPERCASE TOKEN FILTER
6) NGRAM TOKEN FILTER
min_gram ~ max_gram
7) EDGE NGRAM TOKEN FILTER
그외 ...
6. CHARACTER FILTER 종류
Tokenizer를 통과하기 전에 string에 대한 전처리기
3개
mapping
html strip
pattern replace
1) MAPPING CHAR FILTER
맵핑 설정한 문자로 바꾸어 준다
{
"index" : {
"analysis" : {
"char_filter" : {
"my_mapping" : {
"type" : "mapping",
"mappings" : ["ph=>f", "qu=>q"]
}
},
"analyzer" : {
"custom_with_char_filter" : {
"tokenizer" : "standard",
"char_filter" : ["my_mapping"]
},
}
}
}
}
2) HTML STRIP CHAR FILTER
html strip
3) PATTERN REPLACE CHAR FILTER
regex
7. ICU ANALYSIS PLUGIN
ICU? International Components for Unicode
종류
icu_normalization
icu_folding
filtering
icu_collation
Elasticsearch에서 failed to execute script 해결 방법
Elasticsearch의 Index API를 학습하다가 아래와 같은 에러를 만나게 된다.
{
"error": "ElasticsearchIllegalArgumentException[failed to execute script]; nested: ScriptException[scripts of type [inline], operation [update] and lang [groovy] are disabled]; ",
"status": 400
}
에러가 발생하는 이유는,
Elasticsearch에서 scripting 모듈은 기본적으로 groovy를 사용하고 있지만 보안 취약점으로 인하여 비활성화 되어 있기 때문이다.
해결방법으로는 elasticsearch.yml에 script.inline: on 을 추가하면 된다.
2015년 8월 24일 월요일
Elasticsearch에 한국어 형태소분석기 Mecab ko 적용
최근에 Elasticsearch를 정리하면서 MeCab Ko의 Elasticsearch 연동을 정리하지 않은 것 같아서 작성 해 본다.
(사실 SOLR에 MeCab Ko를 먼저 붙였지만, 최근에 Elasticsearch만 정리하고 있다. ㅡㅡ;)
참고) SOLR와 Elasticsearch에서 MeCab을 사용할 때 특수문자 허용 검색하기
http://nocode2k.blogspot.kr/2015/08/mecab-ko-solr-elasticsearch.html
CentOS 6.x 환경에서 SOLR와 Elasticsearch에서 한국어 형태소분석기인 Mecab Ko를 사용하기 위해서는 먼저 아래와 같이 설치 및 환경설정이 필요하다.
(* 8월 20일 현재 은전한닢 프로젝트에서는 mecab ko 사전을 사용하는 스칼라로 개발된 형태소분석기도 배포중이다.)
1.1 C++ 컴파일러 설치
yum install gcc-c++
1.2 Java 다운로드 및 설치
사이트 다운로드 : http://www.oracle.com/technetwork/java/javase/downloads/index.html
리눅스 command 다운로드
32 bit linux use this:
curl -v -j -k -L -H "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u51-b16/jdk-8u51-linux-i586.rpm > jdk-8u51-linux-i586.rpm
For 64 bit:
curl -v -j -k -L -H "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u51-b16/jdk-8u51-linux-x64.rpm > jdk-8u51-linux-x64.rpm
Install the rpm:
rpm -ivh jdk-8u51-linux-i586.rpm
mecab-ko는 한국어 특성에 맞는 기능이 추가된 MeCab의 fork 프로젝트이다.
mecab-ko 다운로드 페이지에서 mecab-ko의 소스를 다운로드 받고 설치한다.
사이트 다운로드: https://bitbucket.org/eunjeon/mecab-ko/downloads
리눅스 command 다운로드 및 설치
wget https://bitbucket.org/eunjeon/mecab-ko/downloads/mecab-0.996-ko-0.9.2.tar.gz
tar -zxvf mecab-0.996-ko-0.9.2.tar.gz
cd mecab-0.996-ko-0.9.2
./configure --with-charset=utf-8
make
make check
make install
# /usr/local/bin 아래에 실행바이너리 파일이, /usr/local/lib 아래에 라이브러리가, 그리고 /usr/local/etc 아래에 설정 파일인 mecabrc가 설치된다.
mecab-ko-dic 다운로드 페이지에서 mecab-ko-dic의 최신버전을 다운로드 받는다.
사이트 다운로드: https://bitbucket.org/eunjeon/mecab-ko-dic/downloads
리눅스 command 다운로드 및 설치
wget https://bitbucket.org/eunjeon/mecab-ko-dic/downloads/mecab-ko-dic-2.0.1-20150707.tar.gz
tar zxvf mecab-ko-dic-2.0.1-20150707.tar.gz
cd mecab-ko-dic-2.0.1-20150707
./configure --with-charset=utf-8
make
make install
# /usr/local/lib/mecab/dic/mecab-ko-dic 아래에 사전이 설치된다.
$ /usr/local/bin/mecab -d /usr/local/lib/mecab/dic/mecab-ko-dic
mecab-ko-dic은 MeCab을 사용하여, 한국어 형태소 분석을 하기 위한 프로젝트입니다.
mecab SL,*,*,*,*,*,*,*
- SY,*,*,*,*,*,*,*
ko SL,*,*,*,*,*,*,*
- SY,*,*,*,*,*,*,*
dic SL,*,*,*,*,*,*,*
은 JX,*,T,은,*,*,*,*
MeCab SL,*,*,*,*,*,*,*
을 JKO,*,T,을,*,*,*,*
사용 NNG,*,T,사용,*,*,*,*
하 XSV,*,F,하,*,*,*,*
여 EC,*,F,여,*,*,*,*
, SC,*,*,*,*,*,*,*
한국어 NNG,*,F,한국어,Compound,*,*,한국/NNG/*+어/NNG/*
형태소 NNG,*,F,형태소,Compound,*,*,형태/NNG/*+소/NNG/*
분석 NNG,*,T,분석,*,*,*,*
을 JKO,*,T,을,*,*,*,*
하 VV,*,F,하,*,*,*,*
기 ETN,*,F,기,*,*,*,*
위한 VV+ETM,*,T,위한,Inflect,VV,ETM,위하/VV/*+ᆫ/ETM/*
프로젝트 NNG,*,F,프로젝트,*,*,*,*
입니다 VCP+EF,*,F,입니다,Inflect,VCP,EF,이/VCP/*+ᄇ니다/EF/*
. SF,*,*,*,*,*,*,*
EOS
사이트 다운로드: https://bitbucket.org/eunjeon/mecab-ko-lucene-analyzer
리눅스 command 다운로드 및 설치
wget https://bitbucket.org/eunjeon/mecab-java/downloads/mecab-java-0.996.tar.gz
tar -zxvf mecab-java-0.996.tar.gz
cd mecab-java-0.996
# Makefile 수정
vi Makefile
# Makefile 에서 INCLUDE 변수에 java include directory를 설정해준다.
INCLUDE=/usr/java/jdk1.8.0_51/include
# Makefile에서 GCC optimization 옵션을 O3에서 O1으로 변경한다.
# 은전한닢에서는 OpenJDK사용시 변경하라고 되어 있으나 Oracle JDK에서도 변경해줘야 한다.
all:
$(CXX) -O1 -c -fpic $(TARGET)_wrap.cxx $(INC)
$(CXX) -shared $(TARGET)_wrap.o -o lib$(TARGET).so $(LIBS)
$(JAVAC) $(PACKAGE)/*.java
$(JAVAC) test.java
$(JAR) cfv $(TARGET).jar $(PACKAGE)/*.class
# 저장
:wq
make
cp libMeCab.so /usr/local/lib
CentOS에서 Elasticsearch를 실행하는 계정의 환경설정파일(예: .bashrc)에 라이브러리 경로를 추가한다.
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib"
export LD_LIBRARY_PATH
./bin/plugin --install analysis-mecab-ko-0.17.0 --url https://bitbucket.org/eunjeon/mecab-ko-lucene-analyzer/downloads/elasticsearch-analysis-mecab-ko-0.17.0.zip
8.1 Elasticsearch 실행
bin/elasticsearch -Djava.library.path=/usr/local/lib
8.2 index 생성
curl -XPUT ‘localhost:9200/INDEX_NAME’
예)
curl -XPUT ‘localhost:9200/eunjeon’
8.3 index close
curl -XPOST 'localhost:9200/eunjeon/_close’
8.3 analyzer 추가
curl -XPUT 'localhost:9200/eunjeon/_settings’ -d ’{
"index": {
“analysis”: {
"analyzer": {
"korean": {
"type": “custom”,
"tokenizer": “mecab_ko_standard_tokenizer”
}
}
}
}
}’
테스트)
curl -XGET 'localhost:9200/eunjeon/_analyze?analyzer=korean\&pretty=true -d '은전한닢 프로젝트'
8.4 index open
curl -XPOST 'localhost:9200/eunjeon/_open’
8.5 type에 대한 _mapping 설정 추가
한글 형태소 분석기 적용된 mapping 추가의 예)
curl -XPUT 'localhost:9200/eunjeon/_mapping/survey’ -d ’{
"properties":{
"title":{
"type":"string",
"analyzer":"korean"
}
}
}’
설정값 확인)
curl -XGET 'localhost:9200/eunjeon/_settings?pretty=1’
[참고 사이트]
은전한닢 프로젝트: http://eunjeon.blogspot.kr
은전한닢 프로젝트 구글 포럼: https://groups.google.com/forum/#!forum/eunjeon
(사실 SOLR에 MeCab Ko를 먼저 붙였지만, 최근에 Elasticsearch만 정리하고 있다. ㅡㅡ;)
참고) SOLR와 Elasticsearch에서 MeCab을 사용할 때 특수문자 허용 검색하기
http://nocode2k.blogspot.kr/2015/08/mecab-ko-solr-elasticsearch.html
CentOS 6.x 환경에서 SOLR와 Elasticsearch에서 한국어 형태소분석기인 Mecab Ko를 사용하기 위해서는 먼저 아래와 같이 설치 및 환경설정이 필요하다.
(* 8월 20일 현재 은전한닢 프로젝트에서는 mecab ko 사전을 사용하는 스칼라로 개발된 형태소분석기도 배포중이다.)
1. GCC컴파일러/JDK설치
1.1 C++ 컴파일러 설치
yum install gcc-c++
1.2 Java 다운로드 및 설치
사이트 다운로드 : http://www.oracle.com/technetwork/java/javase/downloads/index.html
리눅스 command 다운로드
32 bit linux use this:
curl -v -j -k -L -H "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u51-b16/jdk-8u51-linux-i586.rpm > jdk-8u51-linux-i586.rpm
For 64 bit:
curl -v -j -k -L -H "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u51-b16/jdk-8u51-linux-x64.rpm > jdk-8u51-linux-x64.rpm
Install the rpm:
rpm -ivh jdk-8u51-linux-i586.rpm
2. mecab-ko 설치
mecab-ko는 한국어 특성에 맞는 기능이 추가된 MeCab의 fork 프로젝트이다.
mecab-ko 다운로드 페이지에서 mecab-ko의 소스를 다운로드 받고 설치한다.
사이트 다운로드: https://bitbucket.org/eunjeon/mecab-ko/downloads
리눅스 command 다운로드 및 설치
wget https://bitbucket.org/eunjeon/mecab-ko/downloads/mecab-0.996-ko-0.9.2.tar.gz
tar -zxvf mecab-0.996-ko-0.9.2.tar.gz
cd mecab-0.996-ko-0.9.2
./configure --with-charset=utf-8
make
make check
make install
# /usr/local/bin 아래에 실행바이너리 파일이, /usr/local/lib 아래에 라이브러리가, 그리고 /usr/local/etc 아래에 설정 파일인 mecabrc가 설치된다.
3. mecab-ko-dic 설치
mecab-ko-dic 다운로드 페이지에서 mecab-ko-dic의 최신버전을 다운로드 받는다.
사이트 다운로드: https://bitbucket.org/eunjeon/mecab-ko-dic/downloads
리눅스 command 다운로드 및 설치
wget https://bitbucket.org/eunjeon/mecab-ko-dic/downloads/mecab-ko-dic-2.0.1-20150707.tar.gz
tar zxvf mecab-ko-dic-2.0.1-20150707.tar.gz
cd mecab-ko-dic-2.0.1-20150707
./configure --with-charset=utf-8
make
make install
# /usr/local/lib/mecab/dic/mecab-ko-dic 아래에 사전이 설치된다.
4. mecab 테스트
$ /usr/local/bin/mecab -d /usr/local/lib/mecab/dic/mecab-ko-dic
mecab-ko-dic은 MeCab을 사용하여, 한국어 형태소 분석을 하기 위한 프로젝트입니다.
mecab SL,*,*,*,*,*,*,*
- SY,*,*,*,*,*,*,*
ko SL,*,*,*,*,*,*,*
- SY,*,*,*,*,*,*,*
dic SL,*,*,*,*,*,*,*
은 JX,*,T,은,*,*,*,*
MeCab SL,*,*,*,*,*,*,*
을 JKO,*,T,을,*,*,*,*
사용 NNG,*,T,사용,*,*,*,*
하 XSV,*,F,하,*,*,*,*
여 EC,*,F,여,*,*,*,*
, SC,*,*,*,*,*,*,*
한국어 NNG,*,F,한국어,Compound,*,*,한국/NNG/*+어/NNG/*
형태소 NNG,*,F,형태소,Compound,*,*,형태/NNG/*+소/NNG/*
분석 NNG,*,T,분석,*,*,*,*
을 JKO,*,T,을,*,*,*,*
하 VV,*,F,하,*,*,*,*
기 ETN,*,F,기,*,*,*,*
위한 VV+ETM,*,T,위한,Inflect,VV,ETM,위하/VV/*+ᆫ/ETM/*
프로젝트 NNG,*,F,프로젝트,*,*,*,*
입니다 VCP+EF,*,F,입니다,Inflect,VCP,EF,이/VCP/*+ᄇ니다/EF/*
. SF,*,*,*,*,*,*,*
EOS
5. mecab-java 설치
사이트 다운로드: https://bitbucket.org/eunjeon/mecab-ko-lucene-analyzer
리눅스 command 다운로드 및 설치
wget https://bitbucket.org/eunjeon/mecab-java/downloads/mecab-java-0.996.tar.gz
tar -zxvf mecab-java-0.996.tar.gz
cd mecab-java-0.996
# Makefile 수정
vi Makefile
# Makefile 에서 INCLUDE 변수에 java include directory를 설정해준다.
INCLUDE=/usr/java/jdk1.8.0_51/include
# Makefile에서 GCC optimization 옵션을 O3에서 O1으로 변경한다.
# 은전한닢에서는 OpenJDK사용시 변경하라고 되어 있으나 Oracle JDK에서도 변경해줘야 한다.
all:
$(CXX) -O1 -c -fpic $(TARGET)_wrap.cxx $(INC)
$(CXX) -shared $(TARGET)_wrap.o -o lib$(TARGET).so $(LIBS)
$(JAVAC) $(PACKAGE)/*.java
$(JAVAC) test.java
$(JAR) cfv $(TARGET).jar $(PACKAGE)/*.class
# 저장
:wq
make
cp libMeCab.so /usr/local/lib
6. 환경 설정
CentOS에서 Elasticsearch를 실행하는 계정의 환경설정파일(예: .bashrc)에 라이브러리 경로를 추가한다.
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib"
export LD_LIBRARY_PATH
7. Elasticsearch MeCab 플러그인 설치
./bin/plugin --install analysis-mecab-ko-0.17.0 --url https://bitbucket.org/eunjeon/mecab-ko-lucene-analyzer/downloads/elasticsearch-analysis-mecab-ko-0.17.0.zip
8. Elasticsearch 재시작 및 analyzer 테스트
8.1 Elasticsearch 실행
bin/elasticsearch -Djava.library.path=/usr/local/lib
8.2 index 생성
curl -XPUT ‘localhost:9200/INDEX_NAME’
예)
curl -XPUT ‘localhost:9200/eunjeon’
8.3 index close
curl -XPOST 'localhost:9200/eunjeon/_close’
8.3 analyzer 추가
curl -XPUT 'localhost:9200/eunjeon/_settings’ -d ’{
"index": {
“analysis”: {
"analyzer": {
"korean": {
"type": “custom”,
"tokenizer": “mecab_ko_standard_tokenizer”
}
}
}
}
}’
테스트)
curl -XGET 'localhost:9200/eunjeon/_analyze?analyzer=korean\&pretty=true -d '은전한닢 프로젝트'
8.4 index open
curl -XPOST 'localhost:9200/eunjeon/_open’
8.5 type에 대한 _mapping 설정 추가
한글 형태소 분석기 적용된 mapping 추가의 예)
curl -XPUT 'localhost:9200/eunjeon/_mapping/survey’ -d ’{
"properties":{
"title":{
"type":"string",
"analyzer":"korean"
}
}
}’
설정값 확인)
curl -XGET 'localhost:9200/eunjeon/_settings?pretty=1’
[참고 사이트]
은전한닢 프로젝트: http://eunjeon.blogspot.kr
은전한닢 프로젝트 구글 포럼: https://groups.google.com/forum/#!forum/eunjeon
2015년 8월 17일 월요일
Elasticsearch 시작하기 (Elasticsearch Getting Started Webinar)
Elastic 제품 포트폴리오 (The Elastic Product Portfolio)
[이미지 출처: www.elastic.co]
0. Elasticsearch의 특징
- real-time
- distributed
- search
- analytics
관계형 데이터베이스 | elasticsearch |
Database | Index |
Table | Type |
Row | Document |
Column | Field |
Schema | Mapping |
Index | Everything is indexed |
SQL | Query DSL |
1. Elasticsearch 설치
1.1 Java 다운로드 및 설치
1.1.1 사이트 다운로드
1.1.2 리눅스 command 다운로드
32 bit linux use this:
curl -v -j -k -L -H "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u51-b16/jdk-8u51-linux-i586.rpm > jdk-8u51-linux-i586.rpm
For 64 bit:
curl -v -j -k -L -H "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u51-b16/jdk-8u51-linux-x64.rpm > jdk-8u51-linux-x64.rpm
Install the rpm:
rpm -ivh jdk-8u51-linux-i586.rpm
1.2 Elasticsearch 지원 Java 버전
Product and JVM
1.3 Elasticsearch 다운로드
1.3.1 사이트 다운로드
1.3.2 리눅스 command 다운로드
curl -L -O http://download.elasticsearch.org/PATH/TO/VERSION.zip
unzip elasticsearch-$VERSION.zip
cd elasticsearch-$VERSIO
1.3.3 Elasticsearch 디렉토리 구성
$tree -L 2
.
├── LICENSE.txt
├── NOTICE.txt
├── README.textile
├── bin
│ ├── elasticsearch
│ ├── elasticsearch-service-mgr.exe
│ ├── elasticsearch-service-x64.exe
│ ├── elasticsearch-service-x86.exe
│ ├── elasticsearch.bat
│ ├── elasticsearch.in.bat
│ ├── elasticsearch.in.sh
│ ├── plugin
│ ├── plugin.bat
│ └── service.bat
├── config
│ ├── elasticsearch.yml
│ └── logging.yml
├── data
│ └── elasticsearch
├── lib
│ ├── antlr-runtime-3.5.jar
│ ├── apache-log4j-extras-1.2.17.jar
│ ├── asm-4.1.jar
│ ├── asm-commons-4.1.jar
│ ├── elasticsearch-1.6.0.jar
│ ├── groovy-all-2.4.0.jar
│ ├── jna-4.1.0.jar
│ ├── jts-1.13.jar
│ ├── log4j-1.2.17.jar
│ ├── lucene-analyzers-common-4.10.4.jar
│ ├── lucene-core-4.10.4.jar
│ ├── lucene-expressions-4.10.4.jar
│ ├── lucene-grouping-4.10.4.jar
│ ├── lucene-highlighter-4.10.4.jar
│ ├── lucene-join-4.10.4.jar
│ ├── lucene-memory-4.10.4.jar
│ ├── lucene-misc-4.10.4.jar
│ ├── lucene-queries-4.10.4.jar
│ ├── lucene-queryparser-4.10.4.jar
│ ├── lucene-sandbox-4.10.4.jar
│ ├── lucene-spatial-4.10.4.jar
│ ├── lucene-suggest-4.10.4.jar
│ ├── sigar
│ └── spatial4j-0.4.1.jar
├── logs
│ ├── elasticsearch.log
│ ├── elasticsearch_index_indexing_slowlog.log
│ └── elasticsearch_index_search_slowlog.log
└── plugins
├── bigdesk
├── head
└── kopf
2. 기본 설정
elasticsearch.yml
1. cluster.name을 설정한다.
ex: clustre.name: elasticsearch_dev01
2. node.name을 설정한다.
ex: node.name: search_dev01
3. JVM의 스왑을 방지하려면 아래 설정 값을 true로 한다.
bootstrap.mlockall: true
4. 호스트 설정
network.host: 127.0.0.1
5. http port 설정
http.port: 9200
6. Elasticsearch 실행
~/bin/elasticsearch
curl -XGET localhost:9200/_cluster/health
curl -XGET localhost:9200/_cluster/health?pretty
{
"cluster_name" : "elasticsearch_dev01",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 1,
"number_of_data_nodes" : 1,
"active_primary_shards" : 0,
"active_shards" : 0,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 0,
"number_of_pending_tasks" : 0,
"number_of_in_flight_fetch" : 0
}
Head 플러그인 설치
./plugin -i mobz/elasticsearch-head
Marvel 플러그인 설치
./plugin -i elasticsearch/marvel/latest
3. CRUD Operations
http://localhost:9200/_plugin/marvel/sense/index.html
#____________________________________________________
# Document CRUD operation
#____________________________________________________
#____________________________________________________
# Index a JSON document
# ---- Index name
# |
# | ----- Type name
# | |
# | | ---- Doc ID
# | | |
# V V V
PUT /library/books/1
{
"title": "A fly on the wall",
"name": {
"first": "Drosophila",
"last": "Melanogaster"
},
"publish_date": "2015-07-31T12:00:00-0400",
"price": 19.95
}
#____________________________________________________
# 입력한 문서 ID 데이터 얻기
GET /library/books/1
#____________________________________________________
# DOC ID없이 저장하기
POST /library/books/
{
"title": "Adventures of Strange-Foot Smooth",
"name": {
"first": "Xenopus",
"last": "laevis"
},
"publish_date": "2015-07-31T12:12:00-0400",
"price": 5.99
}
#____________________________________________________
# GET 할때는 위에서 자동 생성된 ID가 필요하다.
GET /library/books/AU7iHhAcxZSlo5TsOhLA
#____________________________________________________
# 문서 전체업데이트
PUT /library/books/1
{
"title": "A fly on the wall PART2",
"name": {
"first": "Drosophila",
"last": "Melanogaster"
},
"publish_date": "2015-07-31T12:00:00-0400",
"price": 29.95
}
GET /library/books/1
#____________________________________________________
# 문서 업데이트 API
POST /library/books/1/_update
{
"doc": {
"price" : 10
}
}
GET /library/books/1
#____________________________________________________
# 문서 업데이트 API - 필드추가
POST /library/books/1/_update
{
"doc": {
"cn_price" : 13
}
}
GET /library/books/1
#____________________________________________________
# 문서 삭제
DELETE /library/books/1
GET /library/books/1
# 참고 URL
#______________________________________________
# Bulk indexing and Search
DELETE /library/books/
#______________________________________________
# 여러 문서의 색인이 필요할때, bulk API를 사용하면 된다.
POST /library/books/_bulk
{ "index": {"_id": 1}}
{ "title": "The quick brown fox", "price": 5}
{ "index": {"_id": 2}}
{ "title": "The quick brown fox jumps over the lazy dog", "price": 15}
{ "index": {"_id": 3}}
{ "title": "The quick brown fox jumps over the quick dog", "price": 8 }
{ "index": {"_id": 4}}
{ "title": "Brown fox brown dog", "price": 2}
{ "index": {"_id": 5}}
{ "title": "Lazy dog", "price": 9}
# 참고 URL
4. Query & Search syntax
#____________________________________________________
# 기본적인 검색 수행하기
# 문서 검색 *all*
GET /library/books/_search
#____________________________________________________
# “fox”가 포함된 모든 문서 검색
GET /library/books/_search
{
"query" : {
"match" : {
"title": "fox"
}
}
}
#____________________________________________________
# “quick” and “dog” 검색하는 방법?
GET /library/books/_search
{
"query" : {
"match" : {
"title": “quick dog"
}
}
}
#____________________________________________________
# 문서 내의 구문검색
GET /library/books/_search
{
"query" : {
"match_phrase" : {
"title": “quick dog"
}
}
}
# 참고 URL
#____________________________________________________
# boolean 조합검색
# 검색 형식
GET /library/books/_search
{
"query" : {
"bool": {
"must": [
{}
],
“must_not” : [
{}
],
“should”: [
{}
]
}
}
}
# “quick” and “lazy dog”이 포함된 모든 문서를 찾아보자
GET /library/books/_search
{
"query" : {
"bool": {
"must": [
{
"match": {
“title”:"quick"
}
},
{
"match_phrase": {
"title": “lazy dog"
}
}
]
}
}
}
# 조합검색에서 다른 효과를 주기 위해서 boost를 사용한다.
# 검색결과 품질을 높일 수 있다.
GET /library/books/_search
{
"query" : {
"bool": {
"should": [
{
"match_phrase" :{
"title" : {
"query": “quick dog",
"boost" : 0.5
}
}
},
{
"match_phrase": {
"title": {
"query": “lazy dog"
}
}
}
]
}
}
}
#____________________________________________________
# 검색 키워드 하이라이팅
GET /library/books/_search
{
"query" : {
"bool": {
"should": [
{
"match_phrase" :{
"title" : {
"query": "quick dog",
"boost" : 0.5
}
}
},
{
"match_phrase": {
"title": {
"query": "lazy dog"
}
}
}
]
}
},
"highlight" : {
"fields": {
"title" : {}
}
}
}
#____________________________________________________
# 필터링 검색
# 필터링은 쿼리(query)보다 빠르다.
# 필터링 검색 - 가격이 5$ 이상인 모든 책을 찾기
GET /library/books/_search
{
"query" : {
"filtered": {
"filter": {
"range": {
"price": {
"gte": 5
}
}
}
}
}
}
# 필터링 - 키워드와 가격이 5$ 이상인 모든 책을 찾기
GET /library/books/_search
{
"query" : {
"filtered": {
"query": {
"match": {
"title": “lazy dog"
}
},
"filter": {
"range": {
"price": {
"gte": 5
}
}
}
}
}
}
# 참고 URL
5. Analysis의 이해
# Analysis는 tokenization + token filters 이다.
#____________________________________________________
# 토크나이저와 필터링
GET /library/_analyze?tokenizer=standard
{
“Brown fox brown dog"
}
GET /library/_analyze?tokenizer=standard&filters=lowercase
{
“Brown fox brown dog"
}
# 토크나이저와 필터링 결과에서 유일한 결과만 얻기
GET /library/_analyze?tokenizer=letter&filters=unique,truncate
{
“Brown brown brown fox brown dog"
}
#____________________________________________________
# A tokenize + 0 or more token filters == analyzer
GET /library/_analyze?tokenizer=standard
{
“Brown fox brown dog"
}
#____________________________________________________
# Analysis를 이해하는 것은 매우 중요하다.
# 왜냐하면 토큰나이저는 다양하게 쓸 수 있기 때문이다.
GET /library/_analyze?tokenizer=standard&filters=lowercase,kstem
{
"THE quick.brown_FOx Jumped! $19.95 @ 3.0"
}
GET /library/_analyze?tokenizer=letter&filters=lowercase
{
"THE quick.brown_FOx Jumped! $19.95 @ 3.0"
}
# 참고 URL
6. Mappings overview (schema 정의)
GET /library/_mapping
#____________________________________________________
# 새로운 필드 추가
PUT /library/books/_mapping
{
"books": {
"properties": {
"my_new_field": {
"type": "string"
}
}
}
}
GET /library/_mapping
#____________________________________________________
# analyzers, etc
PUT /library/books/_mapping
{
"books": {
"properties": {
"english_field": {
"type": "string",
"analyzer": "english"
}
}
}
}
GET /library/_mapping
#____________________________________________________
# 필드의 타입과 분석방식을 변경하려면 에러발생!
PUT /library/books/_mapping
{
"books": {
"properties": {
"english_field": {
"type": "long",
"analyzer": "cjk"
}
}
}
}
# 해결방법 - https://gist.github.com/nicolashery/6317643
#____________________________________________________
# long타입의 필드에 double 데이터가 저장된 경우
# 문제를 해결하는 방법
POST /logs/transactions/
{
"id": 234571
}
POST /logs/transactions/
{
"id": 1391.223
}
GET /logs/transactions/_search
{
"query": {
"filtered": {
"filter": {
"range": {
"id": {
"gt": 1391,
"lt": 1392
}
}
}
}
}
}
GET /logs/_mapping
GET /logs/_search
# 문제해결 참고 URL
피드 구독하기:
글 (Atom)