엘라스틱 서치를 쓰면서 기존에 형태소 분석기를 아리랑, 은전한닢, open korea등을 사용했었다.


근데 이번에 6.4버전이 출시 되면서 Elasticsearch에서 기본으로 제공하는 한글 형태소 분석기가 나왔다. 이름은 nori(노리)이다. 

노리는 놀이라는 뜻에서 가져왔으며 mecab-ko-dic 사전을 이용하지만 사전을 압축하므로 기존 형태소 분석기와 비교하여 메모리를 적게 쓰고 훨씬 빠르다.


그럼 Docker에 엘라스틱서치 6.4와 Kibana 6.4를 설치하고 Nori 플러그인을 설치해서 한글 형태소분석기를 사용해보자.


Docker에 Elasticsearch와 Kibana 설치

1
2
docker run --9200:9200 -9300:9300 --name elastic -"discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:6.4.0
docker run ---link elastic:elastic-url -"ELASTICSEARCH_URL=http://elastic-url:9200" -5601:5601 --name kibana docker.elastic.co/kibana/kibana:6.4.0
cs

설치를 완료하고 docker process를 확인하여 정상 동작하는지 확인한다.



Elasticsearch에 Nori 플러그인 설치

엘라스틱서치 bash셀에 접근해서 anaysis-nori를 설치한다.

1
2
3
4
5
6
// elasticsearch의 bash셀 접근
docker exec -it elastic /bin/bash
 
 
// 노리 플러그인 설치
bin/elasticsearch-plugin install analysis-nori
cs


설치가 완료되면 elasticsearch 프로세스를 재 시작 한다. 그러면서 프로세스가 올라올때 Nori 플러그인이 정상적으로 올라오는지 확인해보자.

1
[2018-10-13T01:26:05,498][INFO ][o.e.p.PluginsService     ] [dFC4eSy] loaded plugin [analysis-nori]
cs


그리고 Kibana를 사용해서 분석 플러그인 동작을 확인하자

1
2
3
4
5
6
7
GET _analyze
{
  "analyzer": "nori",
  "text" : "안녕 나는 바보 위들이야."
}
 
 
cs




사전 추가하기

위에 결과를 보면 위들이라는건 하나의 대명사로써 내 별칭인데 '들'이라는 조사를 제거하고 보여주느라 위들이라는 단어가 사라졌다. 이를 해결하기위해 사전을 만들어서 위들을 추가해보자.


먼저 사전에 사용될 사전은 mecab-ko-dic을 사용한다. 플러그인 설치했던것처럼 Elasticsearch에 접속하여 config/userdict_ko.txt를 생성한다. 그리고 그 txtx파일에 "위들"을 추가한다.


그리고 해당 사전을 사용하도록 anaylzer를 생성한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
PUT nori_sample
{
  "settings": {
    "index": {
      "analysis": {
        "tokenizer": {
          "nori_user_dict": {
            "type": "nori_tokenizer",
            "decompound_mode": "mixed",
            "user_dictionary": "userdict_ko.txt"
          }
        },
        "analyzer": {
          "my_analyzer": {
            "type": "custom",
            "tokenizer": "nori_user_dict"
          }
        }
      }
    }
  }
}
cs


그리고 다시한번 조회해보자.

1
2
3
4
5
6
GET nori_sample/_analyze
{
  "analyzer": "my_analyzer",
  "text" : "안녕 나는 바보 위들이야."
}
 
cs

결과를 확인해보면 정상적으로 위들이 형태소분석기에 의해 잘 나누어지는 것을 볼 수 있다.


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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
{
  "tokens": [
    {
      "token": "안녕",
      "start_offset": 0,
      "end_offset": 2,
      "type": "word",
      "position": 0
    },
    {
      "token": "나",
      "start_offset": 3,
      "end_offset": 4,
      "type": "word",
      "position": 1
    },
    {
      "token": "는",
      "start_offset": 4,
      "end_offset": 5,
      "type": "word",
      "position": 2
    },
    {
      "token": "바보",
      "start_offset": 6,
      "end_offset": 8,
      "type": "word",
      "position": 3
    },
    {
      "token": "위들",
      "start_offset": 9,
      "end_offset": 11,
      "type": "word",
      "position": 4
    },
    {
      "token": "이",
      "start_offset": 11,
      "end_offset": 12,
      "type": "word",
      "position": 5
    },
    {
      "token": "야",
      "start_offset": 12,
      "end_offset": 13,
      "type": "word",
      "position": 6
    }
  ]
}
cs



참고

https://www.elastic.co/guide/en/elasticsearch/plugins/6.4/analysis-nori.html

https://www.elastic.co/kr/blog/nori-the-official-elasticsearch-plugin-for-korean-language-analysis

https://www.elastic.co/guide/en/elasticsearch/plugins/6.4/analysis-nori-tokenizer.html

플러그인 클래스

모든 플러그인은 프로그램 관저에서 플러그인을 대표하는 클래스를 내역서 편집기의 개요 페이지에서 선언할  있다. (Menifest OverView 페이지 이기도 하며, 3.2 이상부터는 Activator라고 부른다.)

플러그인과 연관된 정적 리소스에 접근하거나플러그인별 환경설정 또는 기타 상태 정보에 접근해 초기화 하기 위한 메소드를 제공한다.

반드시 필요한 것은 아니지만 플러그인 내역서에 플러그인 클래스가 지정되어 있는 경우에 플러그인이 로딩 되었음을 전달 받는  번째 클래스이며또한 종료되었을  전달 받는 마지막 클래스 이다. (그를 이용해서 해당 플러그인의 시작과 끝의 새로운 동작을 추가할  있다.)

 

UI 사용하는 플러그인의 경우 AbstractUIPlugin 상속받아서 사용하고 UI 사용하지 않을 경우에는 Plugin 상속받는다.

AbstractUIPlugin 자동으로 해당 플러그인의 환경설정을 저장하지만 Plugin 종료  stop() 메소드에 별도로 기재해 주어야 한다.

 

 

Public class FavoritesPlugin extends AbstractUIPlugin {

Private static FavoritesPlugin plugin;

 

Public FavoritesPlugin() {

Plugin = this;

}

 

//  메소드는 플러그인 활성화 시점에 호출 된다.

Public void start(BundleContext context) throws Exception {

Super.start(context)

}

 

//  메소드는 플러그인 중단 시점에 호출된다.

Public void stop(BundleContext context) throws Exception {

Super.stop(context);

Plugin = null;

}

 

//공유 인스턴스를 반환한다.

Public static FavoritesPlugin getDefault() {

Return plugin;

}

 

// 주어진 플러그인 상대 경로에 해당하는 이미지 파일에 대한 이미지 디스크립터를 반환한다.

Public static ImageDescriptor getImageDescriptor(String path) {

Return AbstractUIPlugin.imageDescriptorFromPlugin(

"com.qualityeclipse.favorites", path);

}

}

 

플러그인이 활성화될 이클립스 시스템은 다른 클래스를 로딩하기 전에 가정 먼저 플러그인 클래스의 인스턴스를 생성한다.

플러그인의 일생에 걸쳐 하나의 플러그인 클래스인스턴스만 이클립스 시스템에 의해 사용되며  다른 인스턴스는 생성되지 않는다.

 

일반적으로 플러그인 클래스는 정적 필드를 선언해 자신의 싱글턴 객체를 참고하므로 필요할  플러그인을 통해 쉽게 공유할  있다.

 

PDE, PDE Runtime 카테고리를 확장하여 해당 플러그인의 확장점런타임 라이브러리등을 트리형태로 자세히   있다.


+ Recent posts