正在加载

示例文本分析插件

此示例展示了如何使用稳定插件 API 创建一个简单的“Hello world”文本分析插件。该插件提供了一个自定义的 Lucene 令牌过滤器,该过滤器会剥离除“hello”和“world”之外的所有令牌。

Elastic 提供了一个 Grade 插件 elasticsearch.stable-esplugin,它可以更轻松地开发和打包稳定插件。 本指南中的步骤假定您使用此插件。 但是,您不需要 Gradle 即可创建插件。

  1. 为您的项目创建一个新目录。

  2. 在此示例中,源代码组织在 maintest 目录下。在您的项目主目录中,创建 src/src/main/src/test/ 目录。

  3. 在您的项目主目录中创建以下 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'
    
    }
    
  4. 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);
        }
    }
    
  5. 可以使用以下 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);
        }
    
    }
    
  6. 单元测试可以放在 src/test 目录下。 您将必须为首选的测试框架添加依赖项。

  7. 运行

    gradle bundlePlugin
    

    这将构建 JAR 文件,生成元数据文件,并将它们捆绑到插件 ZIP 文件中。 生成的 ZIP 文件将写入 build/distributions 目录。

  8. 安装插件.

  9. 您可以使用 _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 存储库中的示例分析插件

  1. src 目录中创建一个 yamlRestTest 目录。

  2. yamlRestTest 目录下,为 Java 源代码创建一个 java 文件夹,并为资源创建一个 resources 文件夹。

  3. 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();
        }
    }
    
  4. 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" }
    
  5. 使用以下命令运行测试

    gradle yamlRestTest
    
© . All rights reserved.