Elasticsearch:创建一个 Elasticsearch Ingest 插件

1023 篇文章 596 订阅

在前面的一篇文章 “Elasticsearch:创建属于自己的 Ingest processor” 中,我相信地介绍了如何使用一个模板来创建 Ingest 插件。在今天的文章中,我们使用另外一个方法来做同样的事。我们将使用 eclipse 来生成一个 maven 的项目。

前言

Elasticsearch 是用 Java 编写的,在 Elasticsearch 服务器启动期间,所有各种模块都与 Google Guice 挂钩。 除此之外,还提供了一个插件 API,可以进一步扩展 Elasticsearch 的功能。 在本文中,我们将演示如何为 Elasticsearch 编写一个 Ingest 插件,该插件可以在文档索引被索引之前过滤掉文档字段中的某个关键字。 该示例插件相当简单,但是它为你提供了足够的知识来编写功能全面的 Elasticsearch Ingest 插件,该插件能够在实际建立索引之前处理文档。

Elasticsearch plug-in API

Elasticsearch 从 Elasticsearch 的 plugins 目录加载插件。 每个插件都需要提供一个实现 org.elasticsearch.plugins.Plugin 接口的类。 此外,该类还可以从同一 org.elasticsearch.plugins 包中实现一个确定插件类型的特定接口,例如:

除此之外,每个插件都需要在 plugin-descriptor.properties 文件和可选的 plugin-security.policy 文件中向 Elasticsearch 提供插件元数据,该文件具有插件所需的访问控制权限(由 JDK 指定安全沙箱模型)。

动手实践

创建插件

在今天的练习中,我们将创建一个关键字过来的 ingest 插件。我们将使用 eclipse 来进行展示。首先启动供我们 eclipse:

在上面,我们选择 Maven Project:

我们接下来选择自己额 workspace 位置,并点击 Next:

如果你还没配置好你的 catalog 的话,那么你可以点击上面的 Configure

我们点击 Add Remote Catalog,并添加如下的一个catalog https://repo1.maven.org/maven2/:

等我们配置好 catalog 后。我回到先前的页面:

我们点击 Next 按钮:

我们填入如上的信息,并点击 Finish 按钮。这样我们就生产了一个样本的 plugin。但是这个 plugin 并不是我们所希望的 Ingest plugin 框架。我们需要对它做相应的改动:

FilterIngestPlugin.java

package com.liuxg.elasticsearch.plugin.filter;

import java.util.HashMap;
import java.util.Map;

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

public class FilterIngestPlugin extends Plugin implements IngestPlugin {

@Override
public Map<String, Processor.Factory> getProcessors(Processor.Parameters parameters) {
      Map<String, Processor.Factory> processors = new HashMap<>();
      processors.put(FilterWordProcessor.TYPE, new FilterWordProcessor.Factory());
      return processors;
   }
}

一旦安装了插件,getProcessors方法将返回一个或多个可由 Elasticsearch 使用的 ingest 处理器。 在这种情况下,我们将通过以下实现注册 FilterWordProcess 类提供的一个处理器。我们接着点击上面红色标识的链接,并生产另外一个叫 FilterWordProcessor.java 的文件:

FilterWordProcessor.java

package com.liuxg.elasticsearch.plugin.filter;

import java.util.Map;
import org.elasticsearch.ingest.AbstractProcessor;
import org.elasticsearch.ingest.ConfigurationUtils;
import org.elasticsearch.ingest.IngestDocument;
import org.elasticsearch.ingest.Processor;

public class FilterWordProcessor extends AbstractProcessor {

   public static final String TYPE = "filter_word";

   private String filterWord;

   private String field;

   public FilterWordProcessor(String tag, String filterWord, String field) {
      super(tag);
      this.filterWord = filterWord;
      this.field = field;
   }

   @Override
   public IngestDocument execute(IngestDocument ingestDocument) throws Exception {
      IngestDocument document = ingestDocument;
      String value = document.getFieldValue(field, String.class);
      String clearedValue = value.replace(filterWord, "");
      document.setFieldValue(field, clearedValue);
      return document;
   }

   @Override
   public String getType() {
      return TYPE;
   }

   public static final class Factory implements Processor.Factory {

      @Override
      public Processor create(Map<String, Processor.Factory> registry, String processorTag,
            Map<String, Object> config) throws Exception {

         String field = ConfigurationUtils.readStringProperty(TYPE, processorTag, config, "field");
         String filterWord = ConfigurationUtils.readStringProperty(TYPE, processorTag, config, "filterWord");

         return new FilterWordProcessor(processorTag, filterWord, field);
      }
   }

}

这个 ingest 处理器具有称为 filter_word 的类型,Elasticsearch 使用该类型来对其进行管理。 插件使用在创建处理器时指定的两个属性:表示要过滤的文档字段的字段 field 和表示要在索引文档之前要过滤掉的文档字段中单词的 filterWord。 execute 方法提供了处理器的逻辑。它的实现是非常简单的。

好了。我们基本完成了我们需要改造的代码。

编译插件

我们接着来编译刚才生成的代码。我们使用如下的命令:

mvn clean install

如果不出意外,你将看到和我一样的错误信息:

我们回到文件 RestFilterIngestAction.java 文件,并做相应的修改:

我们做相应的修改后,再重新编译:

我们把生成的 plugin 拷入到 Elasticsearch 的安装根目录中:

cp ./target/releases/filter-ingest-plugin-1.0.0-SNAPSHOT.zip  ~/elastic0/elasticsearch-7.6.2

依赖于你 Elasticsearch 安装的位置不同,上面命令的路径需要根据你自己的安装而改变。

我们进入到 Elasticsearch 安装的根目录中,并打入如下的命令:

./bin/elasticsearch-plugin install  file:Users/liuxg/elastic0/elasticsearch-7.6.2/filter-ingest-plugin-1.0.0-SNAPSHOT.zip

你一定要注意上面的 file:///。 否则你的安装将会不成功。后面紧跟的是你的文件的路径。等安装完后,我们可以使用如下的命令来检查安装是否成功:

./bin/elasticsearch-plugin list

最后一步,也是非常重要的一步。我们需要重新启动我们的 Elasticsearch,这样新的 plugin 才会起作用。

在 Kibana 中进行测试

打开 Kibana,并输入如下的命令:

PUT /_ingest/pipeline/filter_crap
{
  "processors": [
    {
      "filter_word": {
        "field": "description",
        "filterWord": "crap"
      }
    }
  ]
}

在上面,我们想对 description 这个字段进行过滤,而且我们过滤的关键词是 crap,也即是没有用的东西 :)。运行上面的命令,显示:

{
  "acknowledged" : true
}

它表明我们的 filter_word processor 已经被安装好了,并且可以找到了。如果没有安装好,或没有被 Elasticsearch 装载,那么这个命令就会失败。

我们接着执行如下的命令:

PUT /order_data/_doc/1?pipeline=filter_crap
{
   "description": "crap ! Don't buy this."
}
{
  "_index" : "order_data",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

在上面,在 decription 中,有一个 crap 的单词。我们希望经过我们的过滤器后,那么最后在 Elasticsearch 存放的文档中,将不会有 crap 这个单词。这个有点像是我们永远看到的东西都是好的。没有坏的语言 :)

我们接着使用如下的命令来进行检查:

GET order_data/_search
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "order_data",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "description" : " ! Don't buy this."
        }
      }
    ]
  }
}

在上面,我们可以看到在 description 中,没有了crap 这个单词了。它说明了我们的 filter processor 是正常工作的。

如果你对这个整个代码感兴趣的话,那么请访问我的源码:https://github.com/liu-xiao-guo/filter-ingest-plugin

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值