Elasticsearch教程(35) ik中文分词器+pinyin拼音分词器+同义词

这篇具有很好参考价值的文章主要介绍了Elasticsearch教程(35) ik中文分词器+pinyin拼音分词器+同义词。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 前言

闲来无事,发现上一篇ES博客还是去年9月份写的中文ik分词器 pinyin 首字母 search_as_you_type 组合使用,该篇文章还挖了一个大坑没有填,快一年了,是时候填下坑了。

2. 期望的效果

针对股票查询这个特点场景,再结合一般使用者的搜索习惯,暂时确定如下7种期望效果。

2.1 中文名称

Elasticsearch教程(35) ik中文分词器+pinyin拼音分词器+同义词

2.2 全称拼音首字母

Elasticsearch教程(35) ik中文分词器+pinyin拼音分词器+同义词

2.3 中文简称

Elasticsearch教程(35) ik中文分词器+pinyin拼音分词器+同义词

2.4 简称拼音首字母

Elasticsearch教程(35) ik中文分词器+pinyin拼音分词器+同义词

2.5 拼音

Elasticsearch教程(35) ik中文分词器+pinyin拼音分词器+同义词

2.6 中文+拼音

Elasticsearch教程(35) ik中文分词器+pinyin拼音分词器+同义词

2.7 股票编号

Elasticsearch教程(35) ik中文分词器+pinyin拼音分词器+同义词

3. 放弃search_as_you_type类型

上一篇博客Elasticsearch教程(34)中介绍了search_as_you_type类型,通过反复的实验验证,感觉search_as_you_type类型并不符合当前的场景,主要是不够灵活,对于简称“中行”、“建行”的支持不好。所以放弃使用它了,转而使用IK分词器 + pinyin分词器。
search_as_you_type类型对“建设银行”的处理如下:

字段 说明
name 按照 mapping 中的配置进行分析。 如果未配置分析器,则使用索引的默认分词器
name ._2gram 用大小为 2 的 shingle token filter 分词器进行分词
name ._3gram 用大小为 3 的 shingle token filter 分词器进行分词
name ._index_prefix 用 edge ngram token filter 包装上面的 name ._3gram 的分词器

下面对name = "建设银行"这个短语分析

字段 分析后结果
name “建” 、“设”、“银”、“行”
name ._2gram “建 设”、“设 银”、“银 行”
name ._3gram “建 设 银”、“设 银 行”
name ._index_prefix “建”、"建 "、“建 设”、"建 设 "、“建 设 银” 等等

4. pinyin分词器的多音字的错误修改

网上关于pinyin分词器的安装和使用的博客特别多,这里我就不赘述了。但是我得说一个非常重要的问题,目前我写博客时最新的版本8.x还是有这样的问题。虽然GitHub上,已经有人提出了这个Issue,但是目前还没有修复,所以我们就自己动手手动改改吧。

就是多音字“银行”的“行”,pinyin分词器会把“yin hang”错误的转成“yin xing”,当你测试“中国银行”时它是对的,但是“建设银行”时就又错了。不信的话你自己试试看。

这个时候需要修改下图中的jar包解压出来
Elasticsearch教程(35) ik中文分词器+pinyin拼音分词器+同义词
然后修改如下图中文件polyphone.txt,注意千万不要一下子把"yin xing"替换成"yin hang"。

因为“隐形”、“银杏”这些词的拼音就是"yin xing"。这个你需要手动一个一个看好了改,我不确定这个问题是nlp-lang的问题还是pinyin分词器作者改的问题,我看nlp-lang1.7的源代码这个文件里“银行”确实是对的"yin hang"。

改好后,再重新打成nlp-lang-1.7.jar包,替换上图的那个nlp-lang-1.7.jar文件,然后重启ES就行啦。
Elasticsearch教程(35) ik中文分词器+pinyin拼音分词器+同义词

5. 配置同义词文件和自定义字典

1 同义词

在ES的config目录下,新建analysis文件夹,再创建synonyms.txt,配置如下同义词

建设银行,建行
中国银行,中行
中信证券,中信,中证
中水渔业,中渔,中水
苏州科达,科达

2 自定义字典

在ik的config目录下创建ext.dic文本文件,添加一些自定义的扩展词
Elasticsearch教程(35) ik中文分词器+pinyin拼音分词器+同义词
修改如下的配置文件,指定扩展字典的文件名
Elasticsearch教程(35) ik中文分词器+pinyin拼音分词器+同义词
上面操作执行好了后,一定要重启ES,否则是不生效的。

6. 设计ES文档结构

ES的文档设计如下,这就是一个简单的以学习为目的实验性设计,所以设计很简陋。

  • 别人博客会设计tokenizer为ik,filter为pinyin,但是我实验下来不是很理想(针对我的场景而言)
  • 对于ik和pinyin我是分开的,中文+pinyin时用"name.pinyin",纯中文用"name.ik"或"name"
  • 对于name主字段,“analyzer”:“standard”,原因我在上篇博客解释了,有使用的场景
  • 对于name子字段,"keyword"特殊情况使用
  • “firstLetter”,“shortName”,"shortNameFirstLetter"在代码中我没有用到,考虑后期优化先加着
  • 对于无需聚合和排序的keyword,加下"doc_values":false,出于性能优化的目的
PUT pigg_stock_base
{
    "settings":{
        "analysis":{
            "analyzer":{
                "pinyin_analyzer":{
                    "tokenizer":"my_pinyin"
                },
                "ik_max_syno":{
                    "tokenizer":"ik_max_word",
                    "filter":"my_synonym"
                },
                "ik_smart_syno":{
                    "tokenizer":"ik_smart",
                    "filter":"my_synonym"
                }
            },
            "tokenizer":{
                "my_pinyin":{
                    "type":"pinyin",
                    "keep_first_letter":true,
                    "keep_separate_first_letter":true,
                    "keep_full_pinyin":true,
                    "keep_original":false,
                    "limit_first_letter_length":16,
                    "lowercase":true,
                    "remove_duplicated_term":true
                }
            },
            "filter":{
                "my_synonym":{
                    "type":"synonym",
                    "synonyms_path":"analysis/synonyms.txt"
                }
            }
        }
    },
    "mappings":{
        "properties":{
            "name":{
                "type":"text",
                "analyzer":"standard",
                "fields":{
                    "keyword":{
                        "type":"keyword",
                        "ignore_above":256,
                        "doc_values":false
                    },
                    "pinyin":{
                        "type":"text",
                        "analyzer":"pinyin_analyzer"
                    },
                    "ik":{
                        "type":"text",
                        "analyzer":"ik_max_syno",
                        "search_analyzer":"ik_smart_syno"
                    }
                }
            },
            "firstLetter":{
                "type":"keyword",
                "doc_values":false
            },
            "shortName":{
                "type":"keyword",
                "doc_values":false
            },
            "shortNameFirstLetter":{
                "type":"keyword",
                "doc_values":false
            },
            "code":{
                "type":"keyword"
            }
        }
    }
}

插入测试数据

PUT pigg_stock_base/_doc/1
{
  "name": "中国银行",
  "firstLetter": "zgyh",
  "shortName": ["中行"],
  "shortNameFirstLetter": ["zh"],
  "code": "601988"
}

PUT pigg_stock_base/_doc/2
{
  "name": "中国石油",
  "firstLetter": "zgsy",
  "shortName": ["中石油"],
  "shortNameFirstLetter": ["zsy"],
  "code": "601857"
}

PUT pigg_stock_base/_doc/3
{
  "name": "建设银行",
  "firstLetter": "jsyh",
  "shortName": ["建行"],
  "shortNameFirstLetter": ["jh"],
  "code": "601939"
}

PUT pigg_stock_base/_doc/4
{
  "name": "中信证券",
  "firstLetter": "zxzq",
  "shortName": ["中信","中证"],
  "shortNameFirstLetter": ["zx","zz"],
  "code": "600030"
}

PUT pigg_stock_base/_doc/5
{
  "name": "中信建设",
  "firstLetter": "zxjs",
  "shortName": [],
  "shortNameFirstLetter": [],
  "code": "601066"
}

PUT pigg_stock_base/_doc/6
{
  "name": "中水渔业",
  "firstLetter": "zsyy",
  "shortName": ["中水"],
  "shortNameFirstLetter": ["zs"],
  "code": "000798"
}

7. 测试查询DSL语句

GET pigg_stock_base/_search
{
  "query": {
    "match": {
        "name": {
        "query": "中水渔业",
        "operator": "and"
      }
    }
  }
}

GET pigg_stock_base/_search
{
  "query": {
    "match": {
      "name.pinyin": {
        "query": "中国银行",
        "operator": "and"
      }
    }
  }
}

GET pigg_stock_base/_search
{
  "query": {
    "match": {
      "name.ik": {
        "query": "建设银行",
        "operator": "and"
      }
    }
  }
}

GET pigg_stock_base/_search
{
  "query": {
    "match": {
      "name": {
        "query": "中国银",
        "operator": "and"
      }
    }
  }
}

GET pigg_stock_base/_search
{
  "query": {
    "match": {
      "name.pinyin": {
        "query": "中国银",
        "operator": "and"
      }
    }
  }
}

GET pigg_stock_base/_search
{
  "query": {
    "match": {
      "name.pinyin": {
        "query": "中国yh",
        "operator": "and"
      }
    }
  }
}

GET pigg_stock_base/_search
{
  "query": {
    "match": {
      "name.pinyin": {
        "query": "中国yinh",
        "operator": "and"
      }
    }
  }
}

GET pigg_stock_base/_search
{
  "query": {
    "match": {
      "name.pinyin": {
        "query": "中国yinhang",
        "operator": "and"
      }
    }
  }
}

GET pigg_stock_base/_search
{
  "query": {
    "match": {
      "name.pinyin": {
        "query": "zgyh",
        "operator": "and"
      }
    }
  }
}

GET pigg_stock_base/_search
{
  "query": {
    "match": {
      "name.pinyin": {
        "query": "yh",
        "operator": "and"
      }
    }
  }
}

8. 代码

对于后端代码我就不放了,因为是学习ES的代码,有很多地方要优化,我拼接ES查询语句用的是之前我博客Elasticsearch教程(27) ES拼接查询条件的工具类提到的工具,这次又加了matchAnd,主要是为了提供如下的查询:

GET pigg_stock_base/_search
{
  "query": {
    "match": {
      "name": {
        "query": "中银行",
        "operator": "and"
      }
    }
  }
}

前端我用的Vue3 + Element-Plus,其实今年我的学习的目标是啥也可以不学,但是一定要把Vue3学会使用。

<script lang="ts">
export default {
  name: "StockBase"
}
</script>

<template>
  <div class="app-container">
    <el-select
        filterable
        remote
        reserve-keyword
        placeholder="中文/首字母/拼音/代码"
        :remote-method="handleSearch"
        :loading="loading"
    >
      <el-option
          v-for="item in options"
          :key="item.code"
          :label="item.name + '(' + item.code + ')'"
          :value="item.id"
      />
    </el-select>
  </div>
</template>

<script setup lang="ts">
import {ref, reactive} from 'vue'
import {listStockBaseByKeyword} from '@/api/system/stockBase';
import {StockBase} from "@/types/api/system/stockBase";

const loading = ref(false);
const options = ref<StockBase[]>([])

//const dataState = reactive({});

function handleSearch(keyword: string) {
  if (keyword) {
    loading.value = true;
    setTimeout(() => {
      loading.value = false
      listStockBaseByKeyword(keyword).then(({data}) => {
            options.value = data
          }
      );
    }, 200)
  } else {
    options.value = []
  }
}
</script>

<style scoped>

</style>

9. 结语

这个功能主要是为了学习ES的分词器的使用,后端代码有很多优化的地方,比如考虑用ES的异步查询或折叠查询collapse,所以没有必要放后端代码。

还有前端Vue3真的很重要,比Vue2添加了不少功能,光看文档不动手是没有用的,只有不断写页面才能真的学会前端。文章来源地址https://www.toymoban.com/news/detail-406344.html

到了这里,关于Elasticsearch教程(35) ik中文分词器+pinyin拼音分词器+同义词的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ElasticSearch - 基于 拼音分词器 和 IK分词器 模拟实现“百度”搜索框自动补全功能

    目录 一、自动补全 1.1、效果说明 1.2、安装拼音分词器 1.3、自定义分词器 1.3.1、为什么要自定义分词器 1.3.2、分词器的构成 1.3.3、自定义分词器 1.3.4、面临的问题和解决办法 问题 解决方案 1.4、completion suggester 查询 1.4.1、基本概念和语法 1.4.2、示例 1.4.3、示例(黑马旅游)

    2024年02月07日
    浏览(34)
  • Elasticsearch之ik中文分词篇

    es在7.3版本已经支持中文分词,由于中文分词只能支持到单个字进行分词,不够灵活与适配我们平常使用习惯,所以有很多对应中文分词出现,最近使用的是ik分词器,就说说它吧。 安装可以百度下有很多教程,需要注意的是ik分词器的版本要跟es版本对应上,避免出现不必要

    2024年02月02日
    浏览(53)
  • 本地elasticsearch中文分词器 ik分词器安装及使用

    ElasticSearch 内置了分词器,如标准分词器、简单分词器、空白词器等。但这些分词器对我们最常使用的中文并不友好,不能按我们的语言习惯进行分词。 ik分词器就是一个标准的中文分词器。它可以根据定义的字典对域进行分词,并且支持用户配置自己的字典,所以它除了可

    2024年02月05日
    浏览(57)
  • docker-compose安装es以及ik分词同义词插件

    目录 1 前言 2 集成利器Docker 2.1 Docker环境安装 2.1.1 环境检查 2.1.2 在线安装 2.1.3 离线安装 2.2 Docker-Compose的安装 2.2.1 概念简介 2.2.2 安装步骤 2.2.2.1 二进制文件安装 2.2.2.2 离线安装 2.2.2.3 yum安装 3 一键安装ES及Kibana 3.1 yml文件的编写 3.1.1 elasticsearch.yml配置 3.1.2 kibana.yml配置 3.2 一键

    2024年04月23日
    浏览(32)
  • Elasticsearch安装中文分词器IK Analyzer

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 本文介绍IK Analyzer分词器的安装配置、使用以及ES数据迁移。 克隆IK分词器项目,根据README的描述选择对应版本的分支。浏览器访问ES的ip+端口就能看到版本信息,所以我需要切到master分支。 打开pom需要

    2024年02月12日
    浏览(44)
  • ElasticSearch 学习9 spring-boot ,elasticsearch7.16.1实现中文拼音分词搜索

    一、elasticsearch官网下载:Elasticsearch 7.16.1 | Elastic 二、拼音、ik、繁简体转换插件安装 ik分词:GitHub - medcl/elasticsearch-analysis-ik: The IK Analysis plugin integrates Lucene IK analyzer into elasticsearch, support customized dictionary. 拼音分词:GitHub - medcl/elasticsearch-analysis-pinyin: This Pinyin Analysis plugin is

    2024年01月22日
    浏览(40)
  • es elasticsearch 十 中文分词器ik分词器 Mysql 热更新词库

    目录 中文分词器ik分词器 介绍 安装 使用分词器 Ik分词器配置文件 Mysql 热更新词库 介绍 中文分词器按照中文进行分词,中文应用最广泛的是ik分词器 安装 官网下载对应版本zip 下载  放到  plugins 目录 新建 ik文件夹 考入解析zip 重启 es //分成小单词 使用分词器 ik_max_word分成

    2024年02月07日
    浏览(51)
  • Elasticsearch7.8.0版本进阶——IK中文分词器

    通过 Postman 发送 GET 请求查询分词效果,在消息体里,指定要分析的文本 输出结果如下: 由上图输出结果可知,ES 的默认分词器无法识别中文中测试、单词这样的词汇,而是简单的将每个字拆完分为一个词,这样的结果显然不符合我们的使用要求,所以我们需要下载 ES 对应

    2024年02月01日
    浏览(35)
  • Elasticsearch07:ES中文分词插件(es-ik)安装部署

    在中文数据检索场景中,为了提供更好的检索效果,需要在ES中集成中文分词器,因为ES默认是按照英文的分词规则进行分词的,基本上可以认为是单字分词,对中文分词效果不理想。 ES之前是没有提供中文分词器的,现在官方也提供了一些,但是在中文分词领域,IK分词器是

    2024年02月03日
    浏览(69)
  • elasticsearch安装中文分词IK启动异常:java.nio.file.AccessDeniedException

    启动错误信息如下: 问题原因:plugins中添加的ik目录没有权限; 解决方案:进入elasticsearch容器对应plugins目录下,进行 chmod 777 ik 授权即可。

    2024年02月03日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包