Elasticsearch 커스텀 플러그인 개발

📌 Elasticsearch는 기본적으로 강력한 기능을 제공하지만, 특정한 기능을 추가하거나 성능을 개선하려면 커스텀 플러그인을 개발해야 합니다.

  • 플러그인은 Ingest Processor 추가, Query 확장, REST API 확장 등의 기능을 수행할 수 있습니다.

Elasticsearch Plugin 개발 환경 설정

Elasticsearch 플러그인은 Java로 개발되며,
Gradle을 사용하여 빌드하고 Elasticsearch Core API를 활용합니다.


(1) 개발 환경 준비

📌 필수 요구사항

  • JDK 17 이상
  • Elasticsearch 8.x 버전
  • Gradle 7.x 이상
  • IntelliJ IDEA 또는 Eclipse (권장)

(2) 플러그인 프로젝트 생성

Elasticsearch의 플러그인은 Gradle 프로젝트로 구성됩니다.

mkdir my-elasticsearch-plugin
cd my-elasticsearch-plugin

(3) build.gradle 설정

Gradle을 사용하여 Elasticsearch 플러그인 프로젝트를 설정합니다.

plugins {
    id 'java'
    id 'elasticsearch.esplugin' version '8.0.0'
}

group = 'org.elasticsearch.plugin'
version = '1.0'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.elasticsearch:elasticsearch:8.0.0'
    testImplementation 'junit:junit:4.13.2'
}

esplugin {
    name 'my-custom-plugin'
    description 'Custom Elasticsearch Plugin'
    classname 'org.elasticsearch.plugin.MyPlugin'
}

Elasticsearch 플러그인 Gradle 설정을 완료.


커스텀 Ingest Processor 개발

Elasticsearch의 Ingest Processor색인 전에 데이터를 변환하는 기능을 수행합니다.


(1) MyCustomProcessor.java 생성

package org.elasticsearch.plugin;

import org.elasticsearch.ingest.AbstractProcessor;
import org.elasticsearch.ingest.IngestDocument;
import org.elasticsearch.ingest.Processor;

import java.util.Map;

public class MyCustomProcessor extends AbstractProcessor {

    private final String field;
    private final String prefix;

    protected MyCustomProcessor(String tag, String field, String prefix) {
        super(tag);
        this.field = field;
        this.prefix = prefix;
    }

    @Override
    public IngestDocument execute(IngestDocument document) {
        String value = document.getFieldValue(field, String.class);
        document.setFieldValue(field, prefix + value);
        return document;
    }

    @Override
    public String getType() {
        return "my_custom";
    }

    public static class Factory implements Processor.Factory {
        @Override
        public MyCustomProcessor create(Map<String, Processor.Factory> factories, String tag, Map<String, Object> config) {
            String field = (String) config.get("field");
            String prefix = (String) config.get("prefix");
            return new MyCustomProcessor(tag, field, prefix);
        }
    }
}

이 플러그인은 특정 필드의 값을 가져와서 prefix를 추가하는 기능 수행.


(2) MyPlugin.java 생성

package org.elasticsearch.plugin;

import org.elasticsearch.plugins.IngestPlugin;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.ingest.Processor;

import java.util.Map;

public class MyPlugin extends Plugin implements IngestPlugin {
    @Override
    public Map<String, Processor.Factory> getProcessors(Processor.Parameters parameters) {
        return Map.of("my_custom", new MyCustomProcessor.Factory());
    }
}

플러그인을 Elasticsearch에 등록.


(3) 플러그인 빌드 및 설치

./gradlew build
elasticsearch-plugin install file:///path/to/my-custom-plugin.zip

플러그인을 빌드하고 Elasticsearch에 설치.


(4) Ingest Pipeline 설정

PUT _ingest/pipeline/custom_pipeline
{
  "description": "My Custom Processor Pipeline",
  "processors": [
    {
      "my_custom": {
        "field": "message",
        "prefix": "[CUSTOM] "
      }
    }
  ]
}

message 필드에 [CUSTOM] 접두어를 추가하는 Ingest Pipeline 설정.


(5) 테스트 데이터 색인

PUT my-index/_doc/1?pipeline=custom_pipeline
{
  "message": "Hello Elasticsearch"
}
GET my-index/_search

결과: "message": "[CUSTOM] Hello Elasticsearch" 로 변환됨.


Java 클라이언트 (High-Level REST Client) 사용법

Elasticsearch의 Java 클라이언트를 사용하면 Elasticsearch API를 손쉽게 호출 가능.


(1) pom.xml 또는 build.gradle 설정

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-java</artifactId>
    <version>8.0.0</version>
</dependency>

Elasticsearch Java 클라이언트 추가.


(2) Java에서 Elasticsearch 연결

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import co.elastic.clients.transport.endpoints.BooleanResponse;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;

public class ElasticsearchService {

    private static final String ELASTICSEARCH_URL = "http://localhost:9200";

    public static void main(String[] args) throws Exception {
        RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200)).build();
        ElasticsearchClient client = new ElasticsearchClient(new RestClientTransport(restClient));

        // 인덱스 존재 여부 확인
        BooleanResponse exists = client.indices().exists(c -> c.index("my-index"));
        System.out.println("Index exists: " + exists.value());

        // 문서 색인
        client.index(i -> i.index("my-index").id("1").document(Map.of("message", "Hello from Java Client")));

        // 문서 검색
        Query query = Query.of(q -> q.match(m -> m.field("message").query("Hello")));
        var response = client.search(s -> s.index("my-index").query(query), Map.class);

        System.out.println("Search result: " + response.hits().hits());
    }
}

Elasticsearch에 연결하여 색인 및 검색 수행.


Elasticsearch 커스텀 플러그인 개발 정리

기능 설명
Plugin 개발 환경 설정 Java, Gradle, Elasticsearch API 사용
Custom Ingest Processor 색인 전에 데이터를 변환하는 커스텀 프로세서 개발
Java 클라이언트 활용 REST API 호출 없이 Java에서 Elasticsearch 연동 가능

 

+ Recent posts