지금 당장 플러그인 개발이 시급하다면, 

아래 링크와 하단쪽 내용만 확인하세요!

 

(왠지 나 처럼 엄청 헤매고 있는 사람 많을듯...)

 

짬이나서 초성 검색을 위해 필터를 만들고자 마음을 먹고

다시 아래 글을 보았어요.

http://blog.naver.com/tmondev/220918935030

 

ES플러그인 커스터마이징 (3)ㅎㅇㅇㅎ검색 대응하기

티몬의 자동완성ES플러그인 커스터마이징을 다루는 마지막 3부의 주제로 한글 검색에 필수적인 자모 분해...

blog.naver.com

 

소스코드는 그대로 사용해도 무방하다는 댓글을 확인 후..

"어 그냥 만들면 되겠지?" 라고 생각을 하고 열심히 Ctrl + c & Ctrl + v를 하였습니다.

 

근데 플러그인을 적용하는 부분의 내용은 있지만, zip파일은 어떻게 생성할 것이며,

기타 잡다한 것들은 어찌하는지 하나도 모르겠어서 ㅠㅠ

 

게다가 "AbstractTokenFilterFactory를 상속받은 클래스는 어떻게 호출하는거징? " 오징 거징 ㅠㅠ

 

https://m.blog.naver.com/tmondev/220916240095

 

ES플러그인 커스터마이징 (2)핫딜 검색순위 조절하기

들어가며티몬에서는 고객에게 검색 서비스를 제공하기 위해 검색엔진으로 엘라스틱 서치(Elasticsearch, ...

blog.naver.com

이 글을 보면 AbstractPlugin을 상속 받아서 해당 내용에서 처리하는걸 확인 할 수 있는데요.

 

문제는 2버전인가...부터 AbstractPlugin가 없어졌다는 사실..

 

그러다가 외국어로된 블로그(영어지만 코드는 이해할수있으니 ㅋㅋㅋ) 막 찾다보니 AbstractModule?을 사용하는 것도 있었어요.

 

http://jfarrell.github.io/

 

http://jfarrell.github.io/

Creating an Elasticsearch Plugin Elasticsearch is a great search engine built on top of Apache Lucene. We came across the need to add new functionality and did not want to fork Elasticsearch for this. Luckily Elasticsearch comes with a plugin framework. We

jfarrell.github.io

 

일단 첫번째 문제는...AbstractModule을 사용해서 해결해 보도록 ...해보자 였습니다.

public class ChosungPlugin extends AbstractModule {

	private final Settings settings;
	
	public ChosungPlugin(Settings settings) {
		this.settings = settings;
	}
	
	@Override
	protected void configure() {
		bind(JamoTokenFilterFactory.class).asEagerSingleton();
	}

	
}

 

여기서 당면한 두번째 문제...

"압축파일은 어찌 만들지?"

 

저는 플러그인 사용해본건 은전한닢과 아리랑? 같은 한글사전 관련된 플러그인 뿐이었죠.

(이제는 nori를 쓰지만..헤헤)

 

근데 아시다시피 전부 zip파일 이잖아요?

jar 파일은 어찌어찌 만들겠는데...흠...

뭐 저는 잘 모르지만 위에 링크 남긴 글에 해당 내용이 포함 되어 있어요!

 

그래서 그 내용을 바탕으로 만들어서 mvn clean install을 했죠.

 

뭐 약간의 오타를 (복붙했는데 왠 오타, 사실 타이핑이 하고싶어서...ㅠㅠ) 수정하니 잘 돌아갔어요!

 

새로운것도 알게 되었죠!

 

메이븐의 플러그인중 maven-assembly-plugin를 이용하고,

<assembly> 의 태그를 남기면 해당 내용을 수행한다는것 정도?

이걸 통해 zip으로 압축을 한다는것 정도??

 

여튼 이렇게 압축을 하고 해당 플러그인을 es에 심었어요.

 

elasticsearch-plugin.bat install file:///elastic\elasticsearch-7.1.1/elasticsearch-chosungPlugin-7.1.1.zip

 

아니 근데 자꾸 이런 결과가 나오는 거에요 ㅠㅠ

-> Downloading file:///elastic\elasticsearch-7.1.1/elasticsearch-chosungPlugin-7.1.1.zip
[=================================================] 100%??
Exception in thread "main" java.nio.file.NoSuchFileException: C:\elastic\elasticsearch-7.1.1\plugins\.installing-9326766450384708165\plugin-descriptor.properties
        at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:85)
        at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
        at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
        at java.base/sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:235)
        at java.base/java.nio.file.Files.newByteChannel(Files.java:373)
        at java.base/java.nio.file.Files.newByteChannel(Files.java:424)
        at java.base/java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:420)
        at java.base/java.nio.file.Files.newInputStream(Files.java:158)
        at org.elasticsearch.plugins.PluginInfo.readFromProperties(PluginInfo.java:156)
        at org.elasticsearch.plugins.InstallPluginCommand.loadPluginInfo(InstallPluginCommand.java:714)
        at org.elasticsearch.plugins.InstallPluginCommand.installPlugin(InstallPluginCommand.java:793)
        at org.elasticsearch.plugins.InstallPluginCommand.install(InstallPluginCommand.java:776)
        at org.elasticsearch.plugins.InstallPluginCommand.execute(InstallPluginCommand.java:231)
        at org.elasticsearch.plugins.InstallPluginCommand.execute(InstallPluginCommand.java:216)
        at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86)
        at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124)
        at org.elasticsearch.cli.MultiCommand.execute(MultiCommand.java:77)
        at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124)
        at org.elasticsearch.cli.Command.main(Command.java:90)
        at org.elasticsearch.plugins.PluginCli.main(PluginCli.java:47)

 

plugin-descriptor.properties 가 필요한가봐요...

 

아 이건 뭐지 하고 한참을 찾아보니...

위 글 내용의 ES 버전을 보니 0.17.1...뚜둥!!

 

정확히 몇 버전 부터 인지는 모르나, plugin 설치시 해당 내용에는 plugin-descriptor.properties 이게 있어야 하더라고요!

 

그래서 저는 일단 대~충

http://www.technocratsid.com/how-to-create-an-elasticsearch-6-4-1-plugin/

 

How to create an Elasticsearch 6.4.1 Plugin

A plugin provides a way to extend or enhance the basic functionality of Elasticsearch without having to fork it from GitHub. Elasticsearch supports a plugin framework which provides many custom plu…

www.technocratsid.com

위 글을 참고 했어요~!!

이것 말고도 좀 이것저것 참고를 했는데...

여튼 만들고 적용하는데~~

 

같은 오류가 또 나는거에요~?

아 뭐지 하고 한참을 헤맸는데 역시나 오타...(아 복붙할걸...)

파일 이름을 plugin-descriptor.properties로 했어야 했는데 plugin-descrptor.properties로 했더라...는 전설이

(또한 zip압축시 루트에 존재하지 않고 폴더를 하나 지니고 있을 경우 동일한 에러발생)

여튼 이 문제는 지나고 나니!

 

C:\elastic\elasticsearch-7.1.1\bin>elasticsearch-plugin.bat install file:///elastic\elasticsearch-7.1.1/chosung-plugin-1.0.zip
-> Downloading file:///elastic\elasticsearch-7.1.1/chosung-plugin-1.0.zip
[=================================================] 100%??
Exception in thread "main" java.lang.IllegalArgumentException: property [classname] is missing for plugin [chosung-plugin]
        at org.elasticsearch.plugins.PluginInfo.readFromProperties(PluginInfo.java:192)
        at org.elasticsearch.plugins.InstallPluginCommand.loadPluginInfo(InstallPluginCommand.java:714)
        at org.elasticsearch.plugins.InstallPluginCommand.installPlugin(InstallPluginCommand.java:793)
        at org.elasticsearch.plugins.InstallPluginCommand.install(InstallPluginCommand.java:776)
        at org.elasticsearch.plugins.InstallPluginCommand.execute(InstallPluginCommand.java:231)
        at org.elasticsearch.plugins.InstallPluginCommand.execute(InstallPluginCommand.java:216)
        at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86)
        at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124)
        at org.elasticsearch.cli.MultiCommand.execute(MultiCommand.java:77)
        at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124)
        at org.elasticsearch.cli.Command.main(Command.java:90)
        at org.elasticsearch.plugins.PluginCli.main(PluginCli.java:47)

C:\elastic\elasticsearch-7.1.1\bin>elasticsearch-plugin.bat install file:///elastic\elasticsearch-7.1.1/chosung-plugin-1.0.zip
-> Downloading file:///elastic\elasticsearch-7.1.1/chosung-plugin-1.0.zip
[=================================================] 100%??
Exception in thread "main" java.lang.IllegalArgumentException: Unknown properties in plugin descriptor: [plugin]
        at org.elasticsearch.plugins.PluginInfo.readFromProperties(PluginInfo.java:233)
        at org.elasticsearch.plugins.InstallPluginCommand.loadPluginInfo(InstallPluginCommand.java:714)
        at org.elasticsearch.plugins.InstallPluginCommand.installPlugin(InstallPluginCommand.java:793)
        at org.elasticsearch.plugins.InstallPluginCommand.install(InstallPluginCommand.java:776)
        at org.elasticsearch.plugins.InstallPluginCommand.execute(InstallPluginCommand.java:231)
        at org.elasticsearch.plugins.InstallPluginCommand.execute(InstallPluginCommand.java:216)
        at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86)
        at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124)
        at org.elasticsearch.cli.MultiCommand.execute(MultiCommand.java:77)
        at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124)
        at org.elasticsearch.cli.Command.main(Command.java:90)
        at org.elasticsearch.plugins.PluginCli.main(PluginCli.java:47)

이번에는 해당 프로퍼티 안에 정의된 내용이 문제가 있는 친절한 설명입니다.

1. 플러그인으로 사용될 classname을 지정해야 함.

2. plugin 이라는 프로퍼티는 모르는놈이다...(모르는놈이면 그냥 안쓰면 그만 아닌가...)

 

여튼 두가지 친절한 로그로 인해 수정 후 다시 시도~

C:\elastic\elasticsearch-7.1.1\bin>elasticsearch-plugin.bat install file:///elastic\elasticsearch-7.1.1/chosung-plugin-1.0.zip
-> Downloading file:///elastic\elasticsearch-7.1.1/chosung-plugin-1.0.zip
[=================================================] 100%??
Exception in thread "main" java.lang.IllegalStateException: failed to load plugin chosung-plugin due to jar hell
        at org.elasticsearch.plugins.PluginsService.checkBundleJarHell(PluginsService.java:524)
        at org.elasticsearch.plugins.InstallPluginCommand.jarHellCheck(InstallPluginCommand.java:765)
        at org.elasticsearch.plugins.InstallPluginCommand.loadPluginInfo(InstallPluginCommand.java:728)
        at org.elasticsearch.plugins.InstallPluginCommand.installPlugin(InstallPluginCommand.java:793)
        at org.elasticsearch.plugins.InstallPluginCommand.install(InstallPluginCommand.java:776)
        at org.elasticsearch.plugins.InstallPluginCommand.execute(InstallPluginCommand.java:231)
        at org.elasticsearch.plugins.InstallPluginCommand.execute(InstallPluginCommand.java:216)
        at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86)
        at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124)
        at org.elasticsearch.cli.MultiCommand.execute(MultiCommand.java:77)
        at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124)
        at org.elasticsearch.cli.Command.main(Command.java:90)
        at org.elasticsearch.plugins.PluginCli.main(PluginCli.java:47)
Caused by: java.lang.IllegalStateException: jar hell!

"어휴 이건 또 뭐지 jar hell? jar 지옥?ㅋㅋㅋ"

 

이 부분은 여러글을 찾아보니...대강 짐작이 가서 ...

 

위에 빌드시 depency 한 luncene jar가 두개 존재하는데...

이게 이미 es에서 존재하고 사용중인거라 필요가 없다는 내용인듯했다.

 

근데 나는 zip 을 만들때 include로 chosung-plugin-1.0.jar만 지정 했는데도, 

이게 들어와 있으니, 영문을 모를 따름... ㅎㅎ

 

그냥 압축 해제 후 두개의 jar를 포함하지 않은 상태로 다시 zip으로 압축했네요.

(반디집으로 ㅋㅋ)

 

여튼 이후 플러그인 설치는 잘 된듯 하고!

ES를 구동하니...

 

[2019-08-01T16:46:48,649][INFO ][o.e.e.NodeEnvironment    ] [KYN-PC] using [1] data paths, mounts [[(C:)]], net usable_space [91.1gb], net total_space [237.8gb], types [NTFS]
[2019-08-01T16:46:48,668][INFO ][o.e.e.NodeEnvironment    ] [KYN-PC] heap size [989.8mb], compressed ordinary object pointers [true]
[2019-08-01T16:46:48,676][INFO ][o.e.n.Node               ] [KYN-PC] node name [KYN-PC], node ID [w79MYvdUQguvtunBL1Vrgw], cluster name [elasticsearch]
[2019-08-01T16:46:48,680][INFO ][o.e.n.Node               ] [KYN-PC] version[7.1.1], pid[7744], build[default/zip/7a013de/2019-05-23T14:04:00.380842Z], OS[Windows 10/10.0/amd64], JVM[Oracle Corporation/OpenJDK 64-Bit Server VM/12.0.1/12.0.1+12]
[2019-08-01T16:46:48,685][INFO ][o.e.n.Node               ] [KYN-PC] JVM home [C:\elastic\elasticsearch-7.1.1\jdk]
[2019-08-01T16:46:48,687][INFO ][o.e.n.Node               ] [KYN-PC] JVM arguments [-Xms1g, -Xmx1g, -XX:+UseConcMarkSweepGC, -XX:CMSInitiatingOccupancyFraction=75, -XX:+UseCMSInitiatingOccupancyOnly, -Des.networkaddress.cache.ttl=60, -Des.networkaddress.cache.negative.ttl=10, -XX:+AlwaysPreTouch, -Xss1m, -Djava.awt.headless=true, -Dfile.encoding=UTF-8, -Djna.nosys=true, -XX:-OmitStackTraceInFastThrow, -Dio.netty.noUnsafe=true, -Dio.netty.noKeySetOptimization=true, -Dio.netty.recycler.maxCapacityPerThread=0, -Dlog4j.shutdownHookEnabled=false, -Dlog4j2.disable.jmx=true, -Djava.io.tmpdir=C:\Users\comyn\AppData\Local\Temp\elasticsearch, -XX:+HeapDumpOnOutOfMemoryError, -XX:HeapDumpPath=data, -XX:ErrorFile=logs/hs_err_pid%p.log, -Xlog:gc*,gc+age=trace,safepoint:file=logs/gc.log:utctime,pid,tags:filecount=32,filesize=64m, -Djava.locale.providers=COMPAT, -Dio.netty.allocator.type=unpooled, -Delasticsearch, -Des.path.home=C:\elastic\elasticsearch-7.1.1, -Des.path.conf=C:\elastic\elasticsearch-7.1.1\config, -Des.distribution.flavor=default, -Des.distribution.type=zip, -Des.bundled_jd=true]
[2019-08-01T16:46:51,086][WARN ][o.e.b.ElasticsearchUncaughtExceptionHandler] [KYN-PC] uncaught exception in thread [main]
org.elasticsearch.bootstrap.StartupException: java.lang.ClassCastException: class com.mmv.chosung.ChosungPlugin
        at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:163) ~[elasticsearch-7.1.1.jar:7.1.1]
        at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:150) ~[elasticsearch-7.1.1.jar:7.1.1]
        at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86) ~[elasticsearch-7.1.1.jar:7.1.1]
        at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124) ~[elasticsearch-cli-7.1.1.jar:7.1.1]
        at org.elasticsearch.cli.Command.main(Command.java:90) ~[elasticsearch-cli-7.1.1.jar:7.1.1]
        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:115) ~[elasticsearch-7.1.1.jar:7.1.1]
        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:92) ~[elasticsearch-7.1.1.jar:7.1.1]
Caused by: java.lang.ClassCastException: class com.mmv.chosung.ChosungPlugin
        at java.lang.Class.asSubclass(Class.java:3646) ~[?:?]
        at org.elasticsearch.plugins.PluginsService.loadPluginClass(PluginsService.java:581) ~[elasticsearch-7.1.1.jar:7.1.1]
        at org.elasticsearch.plugins.PluginsService.loadBundle(PluginsService.java:555) ~[elasticsearch-7.1.1.jar:7.1.1]
        at org.elasticsearch.plugins.PluginsService.loadBundles(PluginsService.java:471) ~[elasticsearch-7.1.1.jar:7.1.1]
        at org.elasticsearch.plugins.PluginsService.<init>(PluginsService.java:163) ~[elasticsearch-7.1.1.jar:7.1.1]
        at org.elasticsearch.node.Node.<init>(Node.java:308) ~[elasticsearch-7.1.1.jar:7.1.1]
        at org.elasticsearch.node.Node.<init>(Node.java:252) ~[elasticsearch-7.1.1.jar:7.1.1]
        at org.elasticsearch.bootstrap.Bootstrap$5.<init>(Bootstrap.java:211) ~[elasticsearch-7.1.1.jar:7.1.1]
        at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:211) ~[elasticsearch-7.1.1.jar:7.1.1]
        at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:325) ~[elasticsearch-7.1.1.jar:7.1.1]
        at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:159) ~[elasticsearch-7.1.1.jar:7.1.1]
        ... 6 more

어 classcastexception?? 

아 위에서 간과한 문제란 비슷한거 같은데...

plugin 클래스 만들때 AbstractModule를 상속받은게 원인이 아닌가 싶더군요.

AbstractModule는 상당히 과거부터 존재했던 클래스인데...용도가 어디인지 모르겠지만...

다른걸 찾아보기로 하고...

 

두번째 영어 포스팅을 보면 extends Plugin을 사용한걸 확인 할 수 있어요.

 

문제는 이건 목적에 맞는 인터페이스를 상속받어야 한다는건데...

 

얘네들 전부가 관련 플러그인...음 이중에 누가 봐도 AnalysisPlugin...이겠지

 

문제는 또 이걸 어찌 쓰나 찾어봐야해서..

해당 부분은 너무 친절하게 잘 설명 되어있다..ㅎㅎ

AnalysisPlugin.java 상단 코멘트

getCharFilters, getTokenFilters, getTokenizers 등 다양하게 있는데,

나는 토큰필터 니까...그냥 저대로 쓰면 될듯..

그래서 나도 똑같이...

public class ChosungPlugin extends Plugin implements AnalysisPlugin{
	
	@Override
	public Map<String, AnalysisProvider<TokenFilterFactory>> getTokenFilters() {
        return singletonMap("chosung_filter", JamoTokenFilterFactory::new);
    }
}

이렇게 하면 ES안에서 필터이름은 chosung_filter로 사용하면 된겠지비...

 

어휴 이제 다시 한번 zip파일을 만들고...

플러그인 설치하니... jar hell 다시 오류나고...압축해제 후 루씬 관련 jar 제외한 상태로 다시 압축~~

설치 후 ES 가동!

음 아주 잘 되는구만!

 

근데 이 필터가 정말 잘 작동할까 의심을 하며, 티몬 김광문님의 블로그에 있는 스크립트를 돌려 보았다!

 

ES 버전차이가 있어서 아주 약간 수정만 하면 되는데 여튼 잘 된다~!!

이제 이걸 운영서버에 반영만 하면 될듯!!

 

도움되는 글을 남겨주신 티몬의 김광문님 포함 외국인 형아들에게 감사를 표하며, 그럼 안녕.

 

 

추가적으로 이 글을 보고도 헤맬 사람들이 걱정되어 코드 몇줄 더 남겨요...

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.mmv</groupId>
	<artifactId>chosung-plugin</artifactId>
	<version>1.0</version>
	<packaging>jar</packaging>
	<name>chosungPlugin</name>

	<url>http://maven.apache.org</url>

    <properties>
        <elasticsearch.version>7.1.1</elasticsearch.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.plugin.version>3.5.1</maven.compiler.plugin.version>
        <elasticsearch.assembly.descriptor>${basedir}/src/main/assemblies/plugin.xml</elasticsearch.assembly.descriptor>
    </properties>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>${maven.compiler.plugin.version}</version>
				<configuration>
					<source>${maven.compiler.target}</source>
					<target>${maven.compiler.target}</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-assembly-plugin</artifactId>
				<configuration>
					<appendAssemblyId>false</appendAssemblyId>
					<outputDirectory>${project.build.directory}/releases/</outputDirectory>
					<descriptors>
						<descriptor>${elasticsearch.assembly.descriptor}</descriptor>
					</descriptors>
				</configuration>
				<executions>
					<execution>
						<phase>package</phase>
						<goals>
							<goal>attached</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
		<resources>
			<resource>
				<directory>src/main/resources</directory>
				<filtering>true</filtering>
				<includes>
					<include>**/*.properties</include>
				</includes>
			</resource>
		</resources>
	</build>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.elasticsearch</groupId>
			<artifactId>elasticsearch</artifactId>
			<version>${elasticsearch.version}</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.apache.lucene</groupId>
			<artifactId>lucene-analyzers-common</artifactId>
			<version>8.0.0</version>
		</dependency>
	</dependencies>
</project>

pom.xml

 

<?xml version="1.0"?>
<assembly>
	<id>plugin</id>
	<formats>
		<format>zip</format>
	</formats>
	<includeBaseDirectory>false</includeBaseDirectory>
	<fileSets>
		<fileSet>
			<directory>target</directory>
			<outputDirectory>/</outputDirectory>
			<includes>
				<include>*.jar</include>
			</includes>
		</fileSet>
	</fileSets>
	<files>
		<file>
			<source>${project.basedir}/src/main/resources/plugin-descriptor.properties
			</source>
			<outputDirectory>/</outputDirectory>
			<filtered>true</filtered>
		</file>
		<file>
			<source>${project.basedir}/src/main/resources/plugin-security.policy
			</source>
			<outputDirectory>/</outputDirectory>
			<filtered>false</filtered>
		</file>
	</files>
	<dependencySets>
		<dependencySet>
			<outputDirectory>/</outputDirectory>
			<unpack>false</unpack>
		</dependencySet>
	</dependencySets>
</assembly>

plugin.xml

 

description=${project.description}
version=${project.version}
name=${project.artifactId}
classname=com.mmv.chosung.ChosungPlugin
java.version=1.8
elasticsearch.version=7.1.1

plugin-descriptor.properties

 

grant{
permission java.security.AllPermission;
};

plugin-security.policy (이건 뭐 참고용으로 안에 저런 코드가 있는거라던데...일단은 나도 씀)

 

이 외의 코드는 어차피 참조한 링크들 안에 전부 있는것들이기에 생략하기로 할게용~

웹사이트를 돌아다니다보면 ㄱㄴㄷㄹ...순서로

뭔가를 필터 하는 기능이 가끔 있어요.

 

자음 ㄱ으로 시작하는 것에 대해서 나타내려면 어떻게 해야하지...고민을 하긴 개뿔 검색을 해보았죠.

내가 고민하고 생각하는건 이미 다 누군가가 만들어 놨을 테니까!!

 

그러다가 이 글을 보았어요.

https://blog.naver.com/PostView.nhn?blogId=tmondev&logNo=220918935030

 

ES플러그인 커스터마이징 (3)ㅎㅇㅇㅎ검색 대응하기

티몬의 자동완성ES플러그인 커스터마이징을 다루는 마지막 3부의 주제로 한글 검색에 필수적인 자모 분해...

blog.naver.com

와~ 너무 고마운거 있죠?

그리고 글 시작 부분에 아래와 같은 글도 있더라고요~. 넘흐 조하

(다 읽어보니 너무 유익해요! 저 같은 ES허접은 짱짱 유익해요!)

(1) 어떠한 검색어도 의미있는 추천을 
(2) 핫딜 검색순위 조절하기

[출처] ES플러그인 커스터마이징 (3)ㅎㅇㅇㅎ검색 대응하기|작성자 개발몬스터

 

결정적으로 초성검색이 가능한 플러그인을 만드는건데...

저는 초성검색이 가능하면 좋겠지만! 일단은 시작글자 초성기반 필터링을 목적으로 하는거라서요 ㅎㅎ(허접해)

그래서 고심끝에 아주 쉬운 방법으로 접근을...ㅎㅎ

목적 단어에서 시작 글자 초성을 뽑아내서 저장해서 걔로 필터링을 하면 되겠지 하고 생각을 했죠. 므흣.

import java.util.ArrayList;
import java.util.List;

public class ChosungTest {
	// 한글 소리 마디의 Unicode 시작 지점 (가)
	static char UNICODE_SYLLABLES_START_CODEPOINT = 0xAC00;
	
	// 한글의 Unicode 총 글자 수
	static int COUNT_IN_UNICODE = 11172;
	
	// 한글 중성의 Unicode 총 글자 수
	static int COUNT_JUNGSUNG_IN_UNICODE = 21;
	
	// 한글 종성의 Unicode 총 글자 수
	static int COUNT_JONGSUNG_IN_UNICODE = 28;
	
	// 한글 자모 분해의 계산 기본 값 (중성 글자 수 * 종성 글자 수)
	static int JAMO_SPLIT_VALUE = COUNT_JUNGSUNG_IN_UNICODE * COUNT_JONGSUNG_IN_UNICODE;

	protected final static char[] COMPATIBILITY_CHOSUNGs = {  
				            0x3131, 0x3132, 0x3134, 0x3137, 0x3138,     // ㄱ, ㄲ, ㄴ, ㄷ, ㄸ  
				            0x3139, 0x3141, 0x3142, 0x3143, 0x3145,     // ㄹ, ㅁ, ㅂ, ㅃ, ㅅ  
				            0x3146, 0x3147, 0x3148, 0x3149, 0x314A,     // ㅆ, ㅇ, ㅈ, ㅉ, ㅊ  
				            0x314B, 0x314C, 0x314D, 0x314E              // ㅋ, ㅌ, ㅍ, ㅎ  
				    };  
	
	public static char parse(String token) {
		char rtn = ' ';
		
		if(null == token) {
			return rtn;
		}
		
		token = token.trim();
		
		for (int i = 0, length = token.length(); i < length; i++) {
			char ch = token.charAt(i);
			
			// 이게 뭐하는거지 하고 보니까 한글 범위에 대한 값을 찾는 역할 이더라고요. 결과가 0~11172 사이의 값이 나오면 한글인거죠!
			char expectedKorean = (char) (ch - UNICODE_SYLLABLES_START_CODEPOINT);

			System.out.println(ch);
			System.out.println(expectedKorean);
			
			if (expectedKorean >= 0 && expectedKorean <= COUNT_IN_UNICODE) {  
				System.out.println("한글");
				
				int chosung = expectedKorean / JAMO_SPLIT_VALUE;
				
				System.out.println(COMPATIBILITY_CHOSUNGs[chosung]); 
				
				rtn = COMPATIBILITY_CHOSUNGs[chosung];
				break;
			}else {
				System.out.println("노한글");
				rtn = ch;
				break;
			}
		}
		return rtn;
	}
	
	public static void main(String[] args) {
		List<Character> ls = new ArrayList<>();
		
		ls.add(parse("한국"));
		ls.add(parse("korean"));
		ls.add(parse("韓國"));
		ls.add(parse("케이리그"));
		ls.add(parse("k리그"));
		ls.add(parse(""));
		
		System.out.println(ls);
        // 결과 : [ㅎ, k, 韓, ㅋ, k,  ]
	}

}

 

중간 중간 값이 궁금해서 출력문을 넣었어요.

그리고 ...중요한건 초성 분리 공식부분인데..

static int JAMO_SPLIT_VALUE = COUNT_JUNGSUNG_IN_UNICODE * COUNT_JONGSUNG_IN_UNICODE;
...
int chosung = expectedKorean / JAMO_SPLIT_VALUE;

이게 뭐하는거지~ 하고 잘 이해가 안갔어요.

그래서 글을 좀 찾아보았죠.

http://dream.ahboom.net/entry/%ED%95%9C%EA%B8%80-%EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C-%EC%9E%90%EC%86%8C-%EB%B6%84%EB%A6%AC-%EB%B0%A9%EB%B2%95

 

IT 소시민의 소소한 이야기 :: 한글 유니코드 자소 분리 방법

한글 유니코드 자소 분리 방법 한글 유니코드 자소 분리하는 방법을 설명해 보겠습니다. 이제는 많이 알려진 방법이라 드문 내용은 아니지만 제가 알고 있는 지식을 정리하는 차원에서 정리해 봤습니다. 물론 완성된 코드만 사용하셨던 분이거나 처음 접하는 분이라면 이론적 배경을 아시게 될 겁니다. 언어는 자바스크립트를 사용하도록 하겠습니다. 자바스크립트의 문자열은 내부적으로 16비트 유니코드로 처리되고 있기 때문에 여기서 설명하는 원리를 바로 테스트 해 보기 좋습

dream.ahboom.net

이게 분리하는거부터 보면 이해가 어렵지만 위 포스팅 글 내용처럼 합치는걸 먼저 보니 아하! 하고 이해가 가더라고요!

대강 어떤 느낌인지 알았으니까 된거겠죠?

 

결과적으로 이렇게 나온 초성 첫글자 데이터를 저장해서 필터로 사용하면 문제가 안 될거 같아요!

굳이 뭐 ES가 아니어도 상관없는건데...검색기능도 만들어서 나중에 붙이려고 이렇게 하고 있네요.

 

그때는 위 링크들을 바탕으로 플러그인 만들어서 사용해야지~

 

도움주신분들 너무 감사합니다!

+ Recent posts