示例文本分析插件
此示例展示了如何使用稳定插件 API 创建一个简单的“Hello world”文本分析插件。该插件提供了一个自定义的 Lucene 令牌过滤器,该过滤器会剥离除“hello”和“world”之外的所有令牌。
Elastic 提供了一个 Grade 插件 elasticsearch.stable-esplugin
,它可以更轻松地开发和打包稳定插件。 本指南中的步骤假定您使用此插件。 但是,您不需要 Gradle 即可创建插件。
为您的项目创建一个新目录。
在此示例中,源代码组织在
main
和test
目录下。在您的项目主目录中,创建src/
、src/main/
和src/test/
目录。在您的项目主目录中创建以下
build.gradle
构建脚本ext.pluginApiVersion = '8.7.0' ext.luceneVersion = '9.5.0' buildscript { ext.pluginApiVersion = '8.7.0' repositories { mavenCentral() } dependencies { classpath "org.elasticsearch.gradle:build-tools:${pluginApiVersion}" } } apply plugin: 'elasticsearch.stable-esplugin' apply plugin: 'elasticsearch.yaml-rest-test' esplugin { name 'my-plugin' description 'My analysis plugin' } group 'org.example' version '1.0-SNAPSHOT' repositories { mavenLocal() mavenCentral() } dependencies { //TODO transitive dependency off and plugin-api dependency? compileOnly "org.elasticsearch.plugin:elasticsearch-plugin-api:${pluginApiVersion}" compileOnly "org.elasticsearch.plugin:elasticsearch-plugin-analysis-api:${pluginApiVersion}" compileOnly "org.apache.lucene:lucene-analysis-common:${luceneVersion}" //TODO for testing this also have to be declared testImplementation "org.elasticsearch.plugin:elasticsearch-plugin-api:${pluginApiVersion}" testImplementation "org.elasticsearch.plugin:elasticsearch-plugin-analysis-api:${pluginApiVersion}" testImplementation "org.apache.lucene:lucene-analysis-common:${luceneVersion}" testImplementation ('junit:junit:4.13.2'){ exclude group: 'org.hamcrest' } testImplementation 'org.mockito:mockito-core:4.4.0' testImplementation 'org.hamcrest:hamcrest:2.2' }
在
src/main/java/org/example/
中,创建HelloWorldTokenFilter.java
。 此文件为令牌过滤器提供代码,该过滤器会剥离除“hello”和“world”之外的所有令牌package org.example; import org.apache.lucene.analysis.FilteringTokenFilter; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import java.util.Arrays; public class HelloWorldTokenFilter extends FilteringTokenFilter { private final CharTermAttribute term = addAttribute(CharTermAttribute.class); public HelloWorldTokenFilter(TokenStream input) { super(input); } @Override public boolean accept() { if (term.length() != 5) return false; return Arrays.equals(term.buffer(), 0, 4, "hello".toCharArray(), 0, 4) || Arrays.equals(term.buffer(), 0, 4, "world".toCharArray(), 0, 4); } }
可以使用以下
HelloWorldTokenFilterFactory.java
工厂类将此过滤器提供给 Elasticsearch。@NamedComponent
注释用于为过滤器提供hello_world
名称。 这是您在部署插件后可以用来引用过滤器的名称。package org.example; import org.apache.lucene.analysis.TokenStream; import org.elasticsearch.plugin.analysis.TokenFilterFactory; import org.elasticsearch.plugin.NamedComponent; @NamedComponent(value = "hello_world") public class HelloWorldTokenFilterFactory implements TokenFilterFactory { @Override public TokenStream create(TokenStream tokenStream) { return new HelloWorldTokenFilter(tokenStream); } }
单元测试可以放在
src/test
目录下。 您将必须为首选的测试框架添加依赖项。运行
gradle bundlePlugin
这将构建 JAR 文件,生成元数据文件,并将它们捆绑到插件 ZIP 文件中。 生成的 ZIP 文件将写入
build/distributions
目录。安装插件.
您可以使用
_analyze
API 来验证hello_world
令牌过滤器是否按预期工作GET /_analyze
{ "text": "hello to everyone except the world", "tokenizer": "standard", "filter": ["hello_world"] }
如果您使用 Gradle 的 elasticsearch.stable-esplugin
插件,您可以使用 Elasticsearch 的 YAML Rest Test 框架。 这个框架允许您在正在运行的测试集群中加载您的插件,并针对它发出真正的 REST API 查询。 此框架的完整语法超出了本教程的范围,但在 Elasticsearch 存储库中有很多示例。 有关示例,请参阅 Elasticsearch Github 存储库中的示例分析插件。
在
src
目录中创建一个yamlRestTest
目录。在
yamlRestTest
目录下,为 Java 源代码创建一个java
文件夹,并为资源创建一个resources
文件夹。在
src/yamlRestTest/java/org/example/
中,创建HelloWorldPluginClientYamlTestSuiteIT.java
。 此类实现ESClientYamlSuiteTestCase
。import com.carrotsearch.randomizedtesting.annotations.Name; import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate; import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase; public class HelloWorldPluginClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase { public HelloWorldPluginClientYamlTestSuiteIT( @Name("yaml") ClientYamlTestCandidate testCandidate ) { super(testCandidate); } @ParametersFactory public static Iterable<Object[]> parameters() throws Exception { return ESClientYamlSuiteTestCase.createParameters(); } }
在
src/yamlRestTest/resources/rest-api-spec/test/plugin
中,创建10_token_filter.yml
YAML 文件## Sample rest test --- "Hello world plugin test - removes all tokens except hello and world": - do: indices.analyze: body: text: hello to everyone except the world tokenizer: standard filter: - type: "hello_world" - length: { tokens: 2 } - match: { tokens.0.token: "hello" } - match: { tokens.1.token: "world" }
使用以下命令运行测试
gradle yamlRestTest