[Elasticsearch] 플러그인 구조 분석

HI·2022년 5월 4일
0

1. 플러그인 기본


1. 필터 구조

  • NGramFilterFactory.java - NGramTokenFilter.java
  • ChosungFilterFactory.java - ChosungFilter.java
  • SnowballPorterFilterFactory.java - SnowballFilter.java

1.1) ~TokenFilter 구현체

  생성자로 넘겨받은 parser를 이용해 해당 파서가 생성한 결과를 버퍼에 담은 후 단순히 리턴하는 역할을 담당.
  Parser는 TokenFilter 생성을 담당하는 TokenFilterFactory에서 결정하여 넘겨주므로 추후 새로운 파서가 추가되었을 경우에도 이 클래수는 수정을 할 필요가 없다.

1.2) ~TokenFilterFactory

   생성자에서 ES가 넘겨주는 파라미터를 이요해 어떤 Parser를 사용할 지 결정 후 이에 맞는 TokenFilter를 생성해 분석에 이용한다.

1.3) ~Plugin.java

	Map타입의 객체에 등록할 필터와 어떤 이름으로 사용할지 명시해줘 elasticsearch에서 사용할 수 있게 한다.            

2. 토크나이저 구조

  • NGramTokenizerFactory.java

  • NGramTokenizer.java

    	이런식으로 필터/토크나이저 와 팩토리 2개로 처리됨.ngram은 필터와 토크나이저 기능 두개가 있어서 필터와 토크나이저 구성이 다 있다.

3. hello 필터 plugin 예시

[HelloFilter.java]

package com.yaincoding.hanhinsam.filters.hello;

import java.io.IOException;

import org.apache.lucene.analysis.TokenFilter;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;

 //TokenFilter를 확장하는 클래스를 정의
public class helloFilter extends TokenFilter {  

	private final CharTermAttribute charAttr;
	
	public helloFilter(TokenStream input) {
		super(input);
		//jamoUtil = new JamoUtil();
		charAttr = addAttribute(CharTermAttribute.class);
	}
	
	//핵심인 incrementToken()메소드, lucene은 KeywordTokenizer, StandardTokenizer등 여러 토크나이저 클래스를 지원함.
	//토크나이즈가 되면 TokenStream이 생성됨.
	//TokenStream은 분석된 토큰들을 가지고 있음.
	public final boolean incrementToken() throws IOException {
		if (input.incrementToken()) {
            //이부분에서 원하는 분석으로 반환시킴
 			String hello = "hello";
			charAttr.setEmpty().append(hello);
            
            //다른 함수에서 분석로직 생성 후 사용하게끔 방법
           //String chosung = jamoUtil.chosung(charAttr.toString());
		  //charAttr.setEmpty().append(chosung);
			
            
			return true;
		}

		return false;
	}
	
}

[HelloFilterFactory.java]

package com.yaincoding.hanhinsam.filters.hello;

import org.apache.lucene.analysis.TokenStream;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.analysis.AbstractTokenFilterFactory;

import com.yaincoding.hanhinsam.filters.jamo.JamoDecomposeFilter;

public class helloFilterFactory extends AbstractTokenFilterFactory {
	@Inject
	public helloFilterFactory(IndexSettings indexSettings, Environment env, String name,
			Settings settings) {
		super(indexSettings, name, settings);
	}

	@Override
	//toeknFilter를 만드는 TokenFilterFactory 클래스를 확장
	//TokenFilter 객체를 생성하고 리턴해주는 create() 메소드를 재정의함.
	public TokenStream create(TokenStream tokenStream) {
		return new helloFilter(tokenStream);
	}
}

[Plugin.java] 사용할 필터이름 명시.(test_hello, jaon_myfilter)

package com.yaincoding.hanhinsam.plugin;

import java.util.HashMap;
import java.util.Map;

import com.yaincoding.hanhinsam.filters.hello.helloFilterFactory;
import com.yaincoding.hanhinsam.filters.jamo.JamoDecomposeFilterFactory;
import org.elasticsearch.index.analysis.TokenFilterFactory;
import org.elasticsearch.indices.analysis.AnalysisModule.AnalysisProvider;
import org.elasticsearch.plugins.AnalysisPlugin;
import org.elasticsearch.plugins.Plugin;

public class HanHinSamPlugin extends Plugin implements AnalysisPlugin {

	@Override
	public Map<String, AnalysisProvider<TokenFilterFactory>> getTokenFilters() {
		Map<String, AnalysisProvider<TokenFilterFactory>> extra = new HashMap<String, AnalysisProvider<TokenFilterFactory>>();
		extra.put("jaon_myfilter", JamoDecomposeFilterFactory::new);
		extra.put("test_hello", helloFilterFactory::new);
		return extra;
	}
	
	
}

#참고(아리랑 플러그인 Files and classes 정보)
https://www.elastic.co/kr/blog/arirang-analyzer-with-elasticsearch

profile
hi

0개의 댓글