Elasticsearchのプラグインを自作する

## はじめに

Elasticsearchには様々なプラグインがあり、その検索や分析などの機能をカスタマイズしたり、強化したりすることができます。プラグインには、Elasticsearchプロジェクトに含まれる公式のものだけでなく、コミュニティによって作成されたものも数多く存在します。ここでは、プラグインを自作する方法について説明します。

## プラグインの種類

Elasticsearchのプラグインの種類としては、[Analysisプラグイン](https://www.elastic.co/guide/en/elasticsearch/plugins/6.5/analysis.html)や、[Mapperプラグイン](https://www.elastic.co/guide/en/elasticsearch/plugins/6.5/mapper.html)など様々なものがあります。プラグインを自作する前に、自分がElasticsearchにどのような機能を追加したいのか、その機能がどの種類のプラグインに当たるのかを明確にしておく必要があります。

例えば、日本語での検索機能を改善したい場合、[Japanese (kuromoji) Analysis Filter](https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-kuromoji.html)で分割されたトークンに対してさらに処理を行う必要があるとしたら、Analysisプラグイン（トークンフィルター）を自作する必要があります。

## 参考になるソースコードを探す

Elasticsearchのプラグインの自作に関する情報は非常に少なく、日本語のものや、最近のバージョンに関するものは非常に限られています。

GitHubにも様々なプラグインのプロジェクトがありますが、新しいバージョンに対応しているものは限られています。なので最初はElasticsearchの公式プラグイン（Core Plugins）から、参考になるような実装（ソースコード）を探します。

Analysisプラグインを自作する場合は、以下のリポジトリの`analysis-`で始まる名前のプラグインのソースコードを参考にします。

- elasticsearch/plugins at master · elastic/elasticsearch  
https://github.com/elastic/elasticsearch/tree/master/plugins

## プロジェクトの構成

必須のファイルは以下の4つになります。

* `pom.xml`  
  Mavenでのビルドの設定を記述したファイル。
* `plugin.xml`  
  Mavenでのアセンブリの設定を記述したファイルで、プラグインを配布可能なZIP形式にまとめるのに使用される。
* `plugin-descriptor.properties`  
  プラグインのロードに必要な情報（プラグインのJavaクラスやバージョン）を記述したファイル。
* `(プラグイン名)Plugin.java`  
  プラグイン本体のJavaクラスで、これをビルドしたものが起動時に読み込まれる。

これらのファイルは1から記述するのではなく、参考にしたプラグインのプロジェクトをコピーして、一旦ビルドが成功することを確認してから、徐々にカスタマイズしていくのがよいでしょう。

例えば、自分が作成した[elasticsearch-concatenation-token-filter](https://github.com/ryohashimoto/elasticsearch-concatenation-token-filter)では、以下のようになっています。

```
.
├── README.md
├── pom.xml
├── src
│   └── main
│       ├── assemblies
│       │   └── plugin.xml
│       ├── java
│       │   └── com
│       │       └── github
│       │           └── ryohashimoto
│       │               └── elasticsearch
│       │                   ├── index
│       │                   │   └── analysis
│       │                   │       ├── ConcatenationTokenFilter.java
│       │                   │       └── ConcatenationTokenFilterFactory.java
│       │                   └── plugin
│       │                       └── analysis
│       │                           └── ConcatenationTokenFilterPlugin.java
|        └── resources
|            └── plugin-descriptor.properties
└── target
```

## プラグインの実装

プロジェクトの準備ができたらプラグインのソースコードをJavaで実装します。

ここでも、実装するJavaのクラスは既存のプラグインのソースコードを参考にします。

例としてあげた、[elasticsearch-concatenation-token-filter](https://github.com/ryohashimoto/elasticsearch-concatenation-token-filter)ではTokenFilterクラスと、そのFactoryのクラスを実装しています。

* プラグイン(`ConcatenationTokenFilterPlugin.java`)

```java
public class ConcatenationTokenFilterPlugin extends Plugin implements AnalysisPlugin {
    @Override
    public Map<String, AnalysisProvider<TokenFilterFactory>> getTokenFilters() {
        return singletonMap("concatenation", ConcatenationTokenFilterFactory::new);
    }
}
```

* トークンフィルタのFactoryクラス(`ConcatenationTokenFilterFactory.java`)

```java
public class ConcatenationTokenFilterFactory extends AbstractTokenFilterFactory {

    public ConcatenationTokenFilterFactory(IndexSettings indexSettings, Environment environment, String name, Settings settings) {
		super(indexSettings, name, settings);
	}

	@Override
    public TokenStream create(TokenStream tokenStream) {
        return new ConcatenationTokenFilter(tokenStream);
    }
}
```

* トークンフィルタのクラス（`ConcatenationTokenFilter.java`)

```java
public class ConcatenationTokenFilter extends TokenFilter {
  ...
}
```

## ビルドとインストール

プラグインのビルド時に使用するElasticsearchのバージョンと、インストールを行うElasticsearchのバージョンを一致させる必要があるため、`pom.xml`の設定を確認します。

例えば、Elasticsearch 6.5.0をビルドとインストールの両方で使用する場合は以下のようにします。

```xml
<elasticsearch.version>6.5.0</elasticsearch.version>
```

以下のコマンドでビルドを行います。

```
mvn package
```

以下のように、`BUILD SUCCESS`と出力されれば、無事にビルドできたことになります。

```
[INFO] Building zip: /Users/ryo/Repos/elasticsearch-concatenation-token-filter/target/releases/elasticsearch-concatenation-token-filter-6.5.0.1.zip
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.833 s
[INFO] Finished at: 2018-12-09T23:22:14+09:00
[INFO] ------------------------------------------------------------------------
```

インストールを行うには、以下のコマンドを使用します。

```
elasticsearch-plugin install file://(プラグインファイルのパス)
```

ここの`(プラグインファイルのパス)`の部分には、`mvn package`で出力されたZIPファイルのパス（`Building zip:`の後の部分）を指定します。

## プラグインを使用する

インストールが無事にできましたら、プラグインの種類に応じて設定を行って、実際に使用してみます。

Analysisプラグインの場合は、analyzerの設定に適用してみて、実際に正しい結果が得られることを確認します。

## まとめ

簡単ではありますが、Elasticsearchのプラグインを自作して使用する方法をまとめてみました。参考になれば幸いです。

## 参考

* Elasticsearch Plugins and Integrations  
  https://www.elastic.co/guide/en/elasticsearch/plugins/current/index.html
* Help for plugin authors  
  https://www.elastic.co/guide/en/elasticsearch/plugins/current/plugin-authors.html