阿里云ES实现同义词动态更新

Elasticsearch(ES)不支持直接动态加载修改的词典内容,您可以通过安装elasticsearch-analysis-dynamic-synonym插件,实现动态加载OSS仓库词典文件。本文以新网络架构下的阿里云ES实例为例,介绍如何实现同义词动态更新。

背景信息

阿里云Elasticsearch配置在VPC环境下,网络可选性较小,例如公网环境下的词典无法直接加载。Elasticsearch无法直接动态加载修改的词典内容,需要结合场景开发自定义插件,例如使用elasticsearch-analysis-dynamic-synonym实现词典动态加载。

在VPC网络架构下,您可以通过以下流程,实现阿里云Elasticsearch加载外部词典:

  1. 结合业务场景自定义插件。

    例如elasticsearch-analysis-dynamic-synonym插件满足业务场景,编译该插件源码,将正确的插件上传到阿里云Elasticsearch中。

  2. 打通网络。

    词典文件处于公网环境,或与阿里云Elasticsearch实例不在同一VPC下,或在自定义插件中集成了词典所在域名或IP地址,导致网络无法联通,您可以通过以下方式加载外部词典:

    • 优先选择和阿里云Elasticsearch实例处于同一地域下的OSS内网Endpoint作为词典文件的调用地址,减少网络打通等额外操作。各地域的OSS内网Endpoint的详细信息,请参见访问域名和数据中心

    • 如果词典文件存储在与阿里云Elasticsearch实例非同一地域的OSS中,或在其他外部网络环境下,您可以通过以下方式加载词典:

  3. 在阿里云Elasticsearch中创建索引时,通过filter过滤器配置词典文件,然后应用到实际业务中。

注意事项

自定义插件或第三方开源插件的使用和维护(例如bug影响稳定性)等,不在阿里云Elasticsearch的服务范围内,建议您结合业务评估后使用。

操作流程

  1. 步骤一:环境准备

  2. 步骤二:下载elasticsearch-analysis-dynamic-synonym插件并编译源码

  3. 步骤三:安装插件

  4. 步骤四:配置实例私网打通(可选)

  5. 步骤五:配置nginx代理(可选)

  6. 步骤六:验证插件分词效果

步骤一:环境准备

  1. 创建新网络架构下的阿里云Elasticsearch实例,版本为7.10。

    具体操作,请参见创建阿里云Elasticsearch实例

  2. 开通OSS服务,并创建公共读Bucket。

    具体操作,请参见开通OSS服务控制台创建存储空间

  3. 准备词典文件,并上传至OSS。

    具体操作,请参见控制台上传文件。本文使用的示例词典文件为synonym.txt,文件内容如下。词典文件内容

步骤二:下载elasticsearch-analysis-dynamic-synonym插件并编译源码

  1. 下载Elasticsearch 7.x版本对应的elasticsearch-analysis-dynamic-synonym插件源码。

    git clone https://github.com/bells/elasticsearch-analysis-dynamic-synonym
    说明

    在github上下载的master分支源码,对应的Elasticsearch版本为7.x。

  2. 修改pom.xml依赖版本,使其与Elasticsearch版本保持一致。

    修改依赖版本

  3. 重新编译打包。

    说明

    编译过程中可能会出现报错,不同的版本报错存在差异,请结合编译报错校正代码。单击下载编译打包后的7.10版本的elasticsearch-analysis-dynamic-synonym插件

步骤三:安装插件

  1. 登录阿里云Elasticsearch控制台
  2. 上传并安装自定义插件elasticsearch-analysis-dynamic-synonym。

    具体操作,请参见上传与安装自定义插件

  3. 在Kibana控制台,执行以下命令查看安装成功的插件。

    说明

    登录Kibana控制台的具体操作,请参见登录Kibana控制台

    GET _cat/plugins?v

    如果返回结果中包含analysis-dynamic-synonym插件,且版本与Elasticsearch实例版本一致,说明插件安装成功。插件安装结果

步骤四:配置实例私网打通(可选)

如果您的词典文件存储在与阿里云Elasticsearch实例处于同一地域下的OSS中,可忽略此步骤。

  1. 登录阿里云Elasticsearch控制台
  2. 配置Elasticsearch实例私网连接,获取终端节点域名作为访问外部服务的网络链接。

    具体操作,请参见配置实例私网连接。本文配置负载均衡实例监听的端口为8081。

步骤五:配置nginx代理(可选)

如果您的词典文件存储在与阿里云Elasticsearch实例处于同一地域下的OSS中,可忽略此步骤。

  1. 在ECS上安装Nginx。此ECS为步骤四:配置实例私网打通(可选)中,用来转发负载均衡请求的后端服务器。

    具体安装方法请参见Nginx安装配置

  2. 配置nginx.conf文件。

    使用以下配置替换nginx.conf文件中server部分的配置。

    server {
        listen       8081;
        server_name  localhost;
        charset utf-8;
        #access_log  /var/log/nginx/host.access.log  main;
    
        location / {
         #   root   /usr/share/nginx/html;
        #    index  index.html index.htm;
            proxy_pass  https://<yourBucketName>.oss-cn-beijing.aliyuncs.com/synonym.txt;
        }
    
        # redirect server error pages to the static page /50x.html
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    
        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }

    参数

    说明

    listen

    监听端口。必须和负载均衡监听端口一致,本文使用8081。

    proxy_pass

    配置代理转发。本文配置词典所在的OSS Bucket的URL,获取方式请参见控制台分享文件

  3. 加载修改后的配置文件并重启Nginx。

    /usr/local/webserver/nginx/sbin/nginx -s reload            # 重新载入配置文件
    /usr/local/webserver/nginx/sbin/nginx -s reopen            # 重启Nginx

步骤六:验证插件分词效果

  1. 登录目标阿里云Elasticsearch实例的Kibana控制台,根据页面提示进入Kibana主页。
    登录Kibana控制台的具体操作,请参见登录Kibana控制台
    说明 本文以阿里云Elasticsearch 7.10.0版本为例,其他版本操作可能略有差别,请以实际界面为准。
  2. 单击右上角的Dev tools
  3. Console页签中,执行以下命令,创建索引并配置settings,在filter下调用dynamic_synonym接口,通过synonyms_path实现远程词典加载。

    PUT elastic_syn
    {
      "settings": {
        "index":{
          "number_of_shards": "3",
          "number_of_replicas": "1",
          "analysis": {
            "analyzer": {
              "ik_max_syno": {
                "type":"custom",
                "tokenizer": "ik_max_word",
                "filter": [
                  "lowercase",
                  "my_syno_filter"
                ]
              }
            },
            "filter":{
              "my_syno_filter":{
                "type":"dynamic_synonym",
                "synonyms_path":"http://ep-bp1ia595641cd36b****-cn-hangzhou-i.epsrv-bp1n7oc1aot41irv****.cn-hangzhou.privatelink.aliyuncs.com:8081",
                "interval": 30
              }
            }
            }
          }
        },
      "mappings": {
        "properties": {
          "like": {
            "type": "text",
            "analyzer": "ik_max_syno",
            "search_analyzer": "ik_max_syno"
          },
          "tx": {
            "type": "text",
            "analyzer": "ik_max_syno",
            "search_analyzer": "ik_max_syno"
          }
        }
      }
    }

    filter中的参数说明如下,更多参数说明请参见Dynamic Synonym for ElasticSearch

    参数

    说明

    type

    词典文件类型。支持dynamic_synonymdynamic_synonym_graph

    synonyms_path

    词典配置文件路径或URL。请根据具体情况进行设置:

    • 词典文件存储在与阿里云Elasticsearch实例同一地域的OSS中:需要配置为http或https://<yourBucketName>.<OSS内网Endpoint>/synonym.txt,例如https://mybucket.oss-cn-hangzhou-internal.aliyuncs.com/synonym.txt。OSS内网Endpoint的获取方式请参见访问域名和数据中心

    • 词典文件存储在与阿里云Elasticsearch实例非同一地域的OSS中,或在其他外部网络环境下(本文以此为例):需要配置为步骤四:配置实例私网打通(可选)中获取到的终端节点域名。

    interval

    刷新词典的时间间隔,单位为秒,默认:60。

  4. 验证分词效果。

    通过_analyze获取洋芋分词效果。

    GET elastic_syn/_analyze
    {
      "analyzer": "ik_max_syno",
      "text": "洋芋"
    }

    预期结果如下。分词结果

  5. 在远程同义词词典中更新词典内容,并验证分词效果。

    更新后的词典内容如下。更新后的词典内容

    通过_analyze获取仙女分词效果。

    GET elastic_syn/_analyze
    {
      "analyzer": "ik_max_syno",
      "text": "仙女"
    }

    预期结果如下。分词预期结果2