当前位置: 首页 > news >正文

Elasticsearch:简体繁体转换分词器 - STConvert analysis

我的前同事 Medcl 大神,在 github 上也创建了一个转换简体及繁体的分词器。这个在我们的很多的实际应用中也是非常有用的,比如当我的文档是繁体的,但是我们想用中文对它进行搜索。

安装

我们可以按照如下的方法来对这个分词器进行安装:

./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-stconvert/releases/download/v8.2.3/elasticsearch-analysis-stconvert-8.2.3.zip

你可以根据发行的版本及自己的 Elasticsearch 版本来选择合适的版本来安装。

安装完这个插件后,我们必须注意的是:重新启动 Elasticsearch 集群。我们可以使用如下的命令来进行查看:

./bin/elasticsearch-plugin list
$ ./bin/elasticsearch-plugin list
analysis-stconvert

该插件包括如下的部分:

  • analyzer:stconvert
  • tokenizer: stconvert
  • token-filter:stconvert
  • char-filter: stconvert

它还支持如下的配置:

  • convert_type:默认值为 s2t,其它的选项为:
    • s2t:从简体中文转换为繁体中文
    • t2s:从繁体中文转换为简体中文
  • keep_both:默认为 false
  • delimiter:默认是以 , 为分隔符

例子

我们使用如下的例子来进行展示:

PUT /stconvert/
{
  "settings": {
    "analysis": {
      "analyzer": {
        "tsconvert": {
          "tokenizer": "tsconvert"
        }
      },
      "tokenizer": {
        "tsconvert": {
          "type": "stconvert",
          "delimiter": "#",
          "keep_both": false,
          "convert_type": "t2s"
        }
      },
      "filter": {
        "tsconvert": {
          "type": "stconvert",
          "delimiter": "#",
          "keep_both": false,
          "convert_type": "t2s"
        }
      },
      "char_filter": {
        "tsconvert": {
          "type": "stconvert",
          "convert_type": "t2s"
        }
      }
    }
  }
}

在上面,我们创建一个叫做 stconvert 的索引。它定义了一个叫做 tscovert 的 analyzer。如果你想了解更多关于如何定制 analyzer,请阅读我之前的文章 “Elasticsearch: analyzer”。

我们做如下的分词测试:

GET stconvert/_analyze
{
  "tokenizer" : "keyword",
  "filter" : ["lowercase"],
  "char_filter" : ["tsconvert"],
  "text" : "国际國際"
}

上面的命令显示:

{
  "tokens" : [
    {
      "token" : "国际国际",
      "start_offset" : 0,
      "end_offset" : 4,
      "type" : "word",
      "position" : 0
    }
  ]
}

我们可以使用如下的一个定制 analyzer 来对繁体字来进行分词:

PUT index
{
  "settings": {
    "analysis": {
      "char_filter": {
        "tsconvert": {
          "type": "stconvert",
          "convert_type": "t2s"
        }
      },
      "normalizer": {
        "my_normalizer": {
          "type": "custom",
          "char_filter": [
            "tsconvert"
          ],
          "filter": [
            "lowercase"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "foo": {
        "type": "keyword",
        "normalizer": "my_normalizer"
      }
    }
  }
}

我们使用如下的命令来写入一些文档:

PUT index/_doc/1
{
  "foo": "國際"
}

PUT index/_doc/2
{
  "foo": "国际"
}

在上面,我们定义了 foo 字段的分词器为 my_normalizer,那么上面的繁体字 “國際” 将被 char_filter 转换为 “国际”。我们使用如下的命令来进行搜索时:

GET index/_search
{
  "query": {
    "term": {
      "foo": "国际"
    }
  }
}

它返回的结果为:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 0.18232156,
    "hits" : [
      {
        "_index" : "index",
        "_id" : "1",
        "_score" : 0.18232156,
        "_source" : {
          "foo" : "國際"
        }
      },
      {
        "_index" : "index",
        "_id" : "2",
        "_score" : 0.18232156,
        "_source" : {
          "foo" : "国际"
        }
      }
    ]
  }
}

如果我们对它进行 term 搜索:

GET index/_search
{
  "query": {
    "term": {
      "foo": "國際"
    }
  }
}

它返回的结果为:

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 0.18232156,
    "hits" : [
      {
        "_index" : "index",
        "_id" : "1",
        "_score" : 0.18232156,
        "_source" : {
          "foo" : "國際"
        }
      },
      {
        "_index" : "index",
        "_id" : "2",
        "_score" : 0.18232156,
        "_source" : {
          "foo" : "国际"
        }
      }
    ]
  }
}

我们甚至可以结合之前我介绍的 IK 分词器来对繁体字进行分词:

PUT index
{
  "settings": {
    "analysis": {
      "char_filter": {
        "tsconvert": {
          "type": "stconvert",
          "convert_type": "t2s"
        }
      },
      "analyzer": {
        "my_analyzer": {
          "type": "custom",
          "char_filter": [
            "tsconvert"
          ],
          "tokenizer": "ik_smart",
          "filter": [
            "lowercase"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "foo": {
        "type": "text",
        "analyzer": "my_analyzer"
      }
    }
  }
}

在上面,我们先对繁体字进行繁体到简体的转换,然后使用 ik 分词器对它进行分词,之后在进行小写。我们使用如下的命令来进行测试:

GET index/_analyze
{
  "analyzer": "my_analyzer", 
  "text": "我愛北京天安門"
}

上面命令的返回结果是:

{
  "tokens" : [
    {
      "token" : "我",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "CN_CHAR",
      "position" : 0
    },
    {
      "token" : "爱",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "CN_CHAR",
      "position" : 1
    },
    {
      "token" : "北京",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "天安门",
      "start_offset" : 4,
      "end_offset" : 7,
      "type" : "CN_WORD",
      "position" : 3
    }
  ]
}

我们还可以做另外一个测试:

GET index/_analyze
{
  "analyzer": "my_analyzer", 
  "text": "請輸入要轉換簡繁體的中文漢字"
}

结果是:

{
  "tokens" : [
    {
      "token" : "请",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "CN_CHAR",
      "position" : 0
    },
    {
      "token" : "输入",
      "start_offset" : 1,
      "end_offset" : 3,
      "type" : "CN_WORD",
      "position" : 1
    },
    {
      "token" : "要",
      "start_offset" : 3,
      "end_offset" : 4,
      "type" : "CN_CHAR",
      "position" : 2
    },
    {
      "token" : "转换",
      "start_offset" : 4,
      "end_offset" : 6,
      "type" : "CN_WORD",
      "position" : 3
    },
    {
      "token" : "简繁体",
      "start_offset" : 6,
      "end_offset" : 9,
      "type" : "CN_WORD",
      "position" : 4
    },
    {
      "token" : "的",
      "start_offset" : 9,
      "end_offset" : 10,
      "type" : "CN_CHAR",
      "position" : 5
    },
    {
      "token" : "中文",
      "start_offset" : 10,
      "end_offset" : 12,
      "type" : "CN_WORD",
      "position" : 6
    },
    {
      "token" : "汉字",
      "start_offset" : 12,
      "end_offset" : 14,
      "type" : "CN_WORD",
      "position" : 7
    }
  ]
}

相关文章:

  • C语言经典算法实例1:求二维数组最大最小值
  • 【C++入门基础】命名空间 | 缺省参数 | 函数重载 | 引用 | 内联函数
  • VMware安装与配置Linux 虚拟机
  • Code For Better 谷歌开发者之声——我与Android同成长
  • 【深度学习】(五)目标检测——下篇
  • web前端面试高频考点——Vue3.0新增API(生命周期,ref、toRef 和 toRefs 的理解和最佳使用方式)
  • 管理经济学--重点
  • Java学习路线(个人学习总结)
  • 【数据结构】跳表SkipList代码解析(C++)
  • 中医治疗特发性震颤,哪些食物不能吃?
  • 2022 创业方向指南
  • 11.vue3组件化开发(父子组件之间的通信)
  • 戳这里!有机产品认证知识库来了
  • 基于微信小程序和安卓的农产品线上销售购物商城APP
  • QScored大型代码异味和质量度量-数据集
  • android图片蒙层
  • ECMAScript入门(七)--Module语法
  • exif信息对照
  • FineReport中如何实现自动滚屏效果
  • Flannel解读
  • java中具有继承关系的类及其对象初始化顺序
  • Kibana配置logstash,报表一体化
  • Netty源码解析1-Buffer
  • Redis 中的布隆过滤器
  • spring boot下thymeleaf全局静态变量配置
  • underscore源码剖析之整体架构
  • 从tcpdump抓包看TCP/IP协议
  • 二维平面内的碰撞检测【一】
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • 如何在GitHub上创建个人博客
  • 思维导图—你不知道的JavaScript中卷
  • 策略 : 一文教你成为人工智能(AI)领域专家
  • 如何用纯 CSS 创作一个货车 loader
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • # Maven错误Error executing Maven
  • #if和#ifdef区别
  • #Lua:Lua调用C++生成的DLL库
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • (3)选择元素——(17)练习(Exercises)
  • (33)STM32——485实验笔记
  • (C语言)字符分类函数
  • (pojstep1.3.1)1017(构造法模拟)
  • (附源码)springboot“微印象”在线打印预约系统 毕业设计 061642
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (算法二)滑动窗口
  • (万字长文)Spring的核心知识尽揽其中
  • (五十)第 7 章 图(有向图的十字链表存储)
  • (原)本想说脏话,奈何已放下
  • (转)机器学习的数学基础(1)--Dirichlet分布
  • (转)可以带来幸福的一本书
  • .net core 客户端缓存、服务器端响应缓存、服务器内存缓存
  • .NET设计模式(7):创建型模式专题总结(Creational Pattern)
  • .Net转Java自学之路—SpringMVC框架篇六(异常处理)
  • ?.的用法