示例文本分析插件
编辑示例文本分析插件编辑
此示例展示了如何使用稳定插件 API 创建一个简单的“Hello world”文本分析插件。该插件提供了一个自定义 Lucene token 过滤器,它会剥离除“hello”和“world”以外的所有 token。
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”以外的所有 token 的 token 过滤器的代码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
token 过滤器是否按预期工作GET /_analyze { "text": "hello to everyone except the world", "tokenizer": "standard", "filter": ["hello_world"] }
YAML REST 测试编辑
如果您使用的是 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