(6)elasticsearch的分词器

news2024/11/28 4:48:36

1 文档规范化(normalization)

是为了提高召回率。

停用词 、时态转换、大小写、同义词、语气词。

以下的doc1\doc2,经过normalization之后,在搜索的时候是可以匹配到这两个doc。

在这里插入图片描述

我们可以看到,normalization就是把一些词 变成 通用的词

#normalization
GET _analyze
{
  "text": "Mr. Ma is an excellent teacher",
  "analyzer": "standard"
}
#结果:Mr-》mr。Ma-》ma。等等。

2 字符过滤器(character filter)

分词之前的预处理,过滤无用字符

  • HTML Strip Character Filter:html_strip。过滤掉html标签的。
    • 参数:escaped_tags 需要保留的html标签
  • Mapping Character Filter:type是mapping。可以将一些词替换成xxx。
  • Pattern Replace Character Filter:type是pattern_replace。正则替换。
#character filter
##HTML Strip Character Filter
DELETE my_index
#创建分词器my_analyzer 和 过滤器my_char_filter
#把html标签过滤掉,保留a标签
PUT my_index
{
  "settings": {
    "analysis": {
      "char_filter": {
        "my_char_filter":{
          "type":"html_strip",
          "escaped_tags":["a"]
        }
      },
      "analyzer": {
        "my_analyzer":{
          "tokenizer":"keyword",
          "char_filter":["my_char_filter"]
        }
      }
    }
  }
}
GET my_index/_analyze
{
  "analyzer": "my_analyzer",
  "text": "<p>I&apos;m so <a>happy</a>!</p>"
}
#结果:I'm so <a>happy</a>!

##Mapping Character Filter 
DELETE my_index
#把一些词替换成*
PUT my_index
{
  "settings": {
    "analysis": {
      "char_filter": {
        "my_char_filter":{
          "type":"mapping",
          "mappings":[
            "滚 => *",
            "垃 => *",
            "圾 => *"
            ]
        }
      },
      "analyzer": {
        "my_analyzer":{
          "tokenizer":"keyword",
          "char_filter":["my_char_filter"]
        }
      }
    }
  }
}
GET my_index/_analyze
{
  "analyzer": "my_analyzer",
  "text": "你就是个垃圾!滚"
}
#结果:你就是个**!*

##Pattern Replace Character Filter 
#17611001200
DELETE my_index
#正则替换
PUT my_index
{
  "settings": {
    "analysis": {
      "char_filter": {
        "my_char_filter":{
          "type":"pattern_replace",
          "pattern":"(\\d{3})\\d{4}(\\d{4})",
          "replacement":"$1****$2"
        }
      },
      "analyzer": {
        "my_analyzer":{
          "tokenizer":"keyword",
          "char_filter":["my_char_filter"]
        }
      }
    }
  }
}
GET my_index/_analyze
{
  "analyzer": "my_analyzer",
  "text": "您的手机号是17611001200"
}
#结果:您的手机号是176****1200

3 令牌过滤器(token filter)

停用词、时态转换、大小写转换、同义词转换、语气词处理等。比如:has=>have him=>he apples=>apple the/oh/a=>干掉。

https://www.elastic.co/guide/en/elasticsearch/reference/7.10/analysis-synonym-tokenfilter.html

https://www.elastic.co/guide/en/elasticsearch/reference/7.10/analysis-keyword-marker-tokenfilter.html

(这里需要用到ik分词器)

在elasticsearch-7.10.0\config目录下新建analysis目录,新建synonym.txt,内容为

蒙丢丢 ==> 蒙
大G ==> 大
霸道 ==> 霸
daG ==> 大哥
#token filter
DELETE test_index
#在elasticsearch-7.10.0\config目录下新建analysis目录,新建synonym.txt
#创建了个同义词转换,使用的是文件
PUT /test_index
{
  "settings": {
      "analysis": {
        "filter": {
          "my_synonym": {
            "type": "synonym_graph",
            "synonyms_path": "analysis/synonym.txt"
          }
        },
        "analyzer": {
          "my_analyzer": {
            "tokenizer": "ik_max_word",
            "filter": [ "my_synonym" ]
          }
        }
      }
  }
}
GET test_index/_analyze
{
  "analyzer": "my_analyzer",
  "text": ["蒙丢丢,大G,霸道,daG"]
}
#结果:蒙\大\霸\大哥
GET test_index/_analyze
{
  "analyzer": "ik_max_word",
  "text": ["奔驰G级"]
}
#结果:拆分成了 奔驰、g、级 词项

DELETE test_index
#创建了个同义词转换,没有使用文件
#赵,钱,孙,李 的同义词都是 吴
PUT /test_index
{
  "settings": {
      "analysis": {
        "filter": {
          "my_synonym": {
            "type": "synonym",
            "synonyms": ["赵,钱,孙,李=>吴","周=>王"]
          }
        },
        "analyzer": {
          "my_analyzer": {
            "tokenizer": "standard",
            "filter": [ "my_synonym" ]
          }
        }
      }
  }
}
GET test_index/_analyze
{
  "analyzer": "my_analyzer",
  "text": ["赵,钱,孙,李","周"]
}
#结果:吴、王

#大小写转换
GET test_index/_analyze
{
  "tokenizer": "standard",
  "filter": ["lowercase"], 
  "text": ["AASD ASDA SDASD ASDASD"]
}
#结果:都变成了小写
GET test_index/_analyze
{
  "tokenizer": "standard",
  "filter": ["uppercase"], 
  "text": ["asdasd asd asg dsfg gfhjsdf asfdg g"]
}
#结果:都变成了大写
#复杂点的,使用脚本的:长度小于5的变成大写
GET test_index/_analyze
{
  "tokenizer": "standard",
  "filter": {
    "type": "condition",
    "filter":"uppercase",
    "script": {
      "source": "token.getTerm().length() < 5"
    }
  }, 
  "text": ["asdasd asd asg dsfg gfhjsdf asfdg g"]
}

#停用词
DELETE test_index
#把me\you停用了
PUT /test_index
{
  "settings": {
      "analysis": {
        "analyzer": {
          "my_analyzer": {
            "type": "standard",
            "stopwords":["me","you"]
          }
        }
      }
  }
}
GET test_index/_analyze
{
  "analyzer": "my_analyzer", 
  "text": ["Teacher me and you in the china"]
}
#结果里边没有me\you

4 分词器(tokenizer)

主要是将document切词,切割点。

https://www.elastic.co/guide/en/elasticsearch/reference/7.10/analysis-standard-tokenizer.html

#分词器 tokenizer
#standard以空格进行切词的,对英文支持比较好
GET test_index/_analyze
{
  "analyzer": "standard", 
  "text": ["Teacher me and you in the china"]
}
#结果:各个单词
GET test_index/_analyze
{
  "tokenizer": "ik_max_word",
  "text": ["我爱北京天安门","天安门上太阳升"]
}
#结果:把一些特定的词拆分,比较符合中文的习惯

5 常见分词器:

  • standard analyzer:默认分词器,中文支持的不理想,会逐字拆分。
  • pattern tokenizer:以正则匹配分隔符,把文本拆分成若干词项。
  • simple pattern tokenizer:以正则匹配词项,速度比pattern tokenizer快。
  • whitespace analyzer:以空白符分隔 Tim_cookie

6 自定义分词器:custom analyzer

  • char_filter:内置或自定义字符过滤器 。
  • token filter:内置或自定义token filter 。
  • tokenizer:内置或自定义分词器。
#自定义分词器
DELETE custom_analysis
PUT custom_analysis
{
  "settings": {
    "analysis": {
      "char_filter": {
        "my_char_filter": {
          "type": "mapping",
          "mappings": [
            "& => and",
            "| => or"
          ]
        },
        "html_strip_char_filter":{
          "type":"html_strip",
          "escaped_tags":["a"]
        }
      },
      "filter": {
        "my_stopword": {
          "type": "stop",
          "stopwords": [
            "is",
            "in",
            "the",
            "a",
            "at",
            "for"
          ]
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "pattern",
          "pattern": "[ ,.!?]"
        }
      }, 
      "analyzer": {
        "my_analyzer":{
          "type":"custom",
          "char_filter":["my_char_filter","html_strip_char_filter"],
          "filter":["my_stopword","lowercase"],
          "tokenizer":"my_tokenizer"
        }
      }
    }
  }
}

GET custom_analysis/_analyze
{
  "analyzer": "my_analyzer",
  "text": ["What is ,<a>as.df</a>  ss<div> in ? &</div> | is ! in the a at for "]
}

7 中文分词器:ik分词

自定义词库和热更新可以参考它的github主页介绍。

  1. 安装和部署

    • ik下载地址:https://github.com/medcl/elasticsearch-analysis-ik
    • Github加速器:https://github.com/fhefh2015/Fast-GitHub
    • 创建插件文件夹 cd your-es-root/plugins/ && mkdir ik
    • 将插件解压缩到文件夹 your-es-root/plugins/ik
    • 重新启动es
  2. IK文件描述

    • IKAnalyzer.cfg.xml:IK分词配置文件
  • 主词库:main.dic
    • 英文停用词:stopword.dic,不会建立在倒排索引中
    • 特殊词库:
      • quantifier.dic:特殊词库:计量单位等
      • suffix.dic:特殊词库:行政单位
      • surname.dic:特殊词库:百家姓
      • preposition:特殊词库:语气词
    • 自定义词库:网络词汇、流行词、自造词等
自定义词库过程:
1、在elasticsearch-7.10.0\plugins\ik\config下创建custom目录,创建文件wxd_extra.dic、wxd_extra2.dic
2、文件内容
#wxd_extra.dic
蒙丢丢
#wxd_extra2.dic
渣男
渣女
3、修改配置文件IKAnalyzer.cfg.xml
<!--用户可以在这里配置自己的扩展字典 -->
<entry key="ext_dict">custom\wxd_extra.dic;custom\wxd_extra2.dic</entry>
3、重启es,再次查询
GET custom_analysis/_analyze
{
  "analyzer": "ik_max_word",
  "text": ["蒙丢丢","渣男","渣女"]
}
#添加自定义词库之前结果:蒙、丢、丢、渣、男、渣、女
#添加自定义词库之后结果:蒙丢丢、渣男、渣女
  1. ik提供的两种analyzer:

    1. ik_max_word 会将文本做最细粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌”,会穷尽各种可能的组合,适合 Term Query;
    2. ik_smart 会做最粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国、国歌”,适合 Phrase 查询。

    8 ik热更新

    1. 远程词库文件
      1. 优点:上手简单
      2. 缺点:
        1. 词库的管理不方便,要操作直接操作磁盘文件,检索页很麻烦
        2. 文件的读写没有专门的优化性能不好
        3. 多一层接口调用和网络传输
    2. ik访问数据库
      1. MySQL驱动版本兼容性
        1. https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-versions.html
        2. https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-versions.html
      2. 驱动下载地址
        1. https://mvnrepository.com/artifact/mysql/mysql-connector-java

8 ik热更新

目前该插件支持热更新 IK 分词,通过上文在 IK 配置文件中提到的如下配置

 	<!--用户可以在这里配置远程扩展字典 -->
	<entry key="remote_ext_dict">location</entry>
 	<!--用户可以在这里配置远程扩展停止词字典-->
	<entry key="remote_ext_stopwords">location</entry>

其中 location 是指一个 url,比如 http://yoursite.com/getCustomDict,该请求只需满足以下两点即可完成分词热更新。

  1. 该 http 请求需要返回两个头部(header),一个是 Last-Modified,一个是 ETag,这两者都是字符串类型,只要有一个发生变化,该插件就会去抓取新的分词进而更新词库。
  2. 该 http 请求返回的内容格式是一行一个分词,换行符用 \n 即可。

满足上面两点要求就可以实现热更新分词了,不需要重启 ES 实例。

可以将需自动更新的热词放在一个 UTF-8 编码的 .txt 文件里,放在 nginx 或其他简易 http server 下,当 .txt 文件修改时,http server 会在客户端请求该文件时自动返回相应的 Last-Modified 和 ETag。可以另外做一个工具来从业务系统提取相关词汇,并更新这个 .txt 文件。

基于远程词库的热更新

  1. 优点:上手简单
  2. 缺点:
    1. 词库的管理不方便,要操作直接操作磁盘文件,检索页很麻烦
    2. 文件的读写没有专门的优化性能不好
    3. 多一层接口调用和网络传输

需要:一个普通的springboot项目(controller)+ 词库文件

@RestController
@RequestMapping(value = "/api")
public class HomeController {
    @RequestMapping(value = "hotWord")
    public void hotword(HttpServletResponse response, Integer wordlib) throws IOException {
        File file = new File(wordlib == 1 ? "./files/wxd_extend.dic" : "./files/wxd_stopword.dic");
        FileInputStream fis = new FileInputStream(file);
        byte[] buffer = new byte[(int) file.length()];
        response.setContentType("text/plain;charset=utf-8");
        response.setHeader("Last-Modified", String.valueOf(buffer.length));
        response.setHeader("ETag", String.valueOf(buffer.length));
        int offset = 0;
        while (fis.read(buffer, offset, buffer.length - offset) != -1) {

        }
        OutputStream out = response.getOutputStream();
        out.write(buffer);
        out.flush();
        fis.close();
    }
}

在springboot项目的目录下新建files目录,里边分别有两个文件wxd_extend.dic、wxd_stopword.dic,此时都是空的

修改配置文件IKAnalyzer.cfg.xml

<!--用户可以在这里配置远程扩展字典 -->
<entry key="remote_ext_dict">http://localhost:9081/api/hotWord?wordlib=1</entry>
<!--用户可以在这里配置远程扩展停止词字典-->
<entry key="remote_ext_stopwords">http://localhost:9081/api/hotWord?wordlib=2</entry>

在修改了wxd_extend.dic、wxd_stopword.dic之后,es会自动去请求远程字典的地址。

#文件内容都为空的时候
GET custom_analysis/_analyze
{
  "analyzer": "ik_max_word",
  "text": ["张明","太阳"]
}
#结果:张、明、太阳

#wxd_extend.dic中添加张明,es会加载文件内容,之后,再测测试:张、明  变成了 张明
#wxd_stopword.dic中添加太阳,es会加载文件内容,之后,再测测试:太阳 不再显示了

在这里插入图片描述

=非常重要的注意===文件一定要是UTF-8 编码的。

在这里插入图片描述

基于mysql的热更新

  1. MySQL驱动版本兼容性
    1. https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-versions.html
    2. https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-versions.html
  2. 驱动下载地址
    1. https://mvnrepository.com/artifact/mysql/mysql-connector-java

需要:ik的源码+ mysql

1、下载ik的源码,https://github.com/medcl/elasticsearch-analysis-ik/releases

在这里插入图片描述

2、pom中添加mysql连接,在config文件里边创建一个jdbc配置

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
#jdbc-reload.properties
jdbc.url=jdbc:mysql://localhost:3306/es_ik_use?serverTimezone=UTC
jdbc.user=root
jdbc.password=123456
jdbc.reload.sql=select word from ik_extword
jdbc.reload.stopword.sql=select stopword as word from ik_stopword
jdbc.reload.interval=1000

根据org.wltea.analyzer.dic.Dictionary 模仿写出通过jdbc的加载热数据

根据org.wltea.analyzer.dic.Monitor模仿写出jdbc的monitor

3、打包

把target/releases下的zip包,复制到elasticsearch-7.10.0\plugins下,解压,重新命名为ik。

再次检查jdbc-reload.properties的内容是否正确。

之后,把mysql的jar包放到ik文件里边。

在这里插入图片描述

4、启动es,测试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/474461.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

带你认识什么是BMS(电池管理系统)

文章目录 概述BMS的硬件拓扑BMS的电气架构BMS的功能BMS的总压采集&#xff08;主板功能&#xff09;BMS的电流采集&#xff08;主板功能&#xff09;BMS的电芯电压和温度采集&#xff08;从板功能&#xff09;BMS的SOC、SOP和SOH&#xff08;ASW计算&#xff09;BSM的绝缘检测B…

ES6新特性(1)

目录 一、字符串扩展 &#xff08;1&#xff09;字符串遍历器接口&#xff08;for...of...&#xff09; &#xff08;2&#xff09;模板字符串 二、字符串新增方法 &#xff08;1&#xff09;包含方法 &#xff08;2&#xff09;重复方法 &#xff08;3&#xff09;补全方…

MySQL数据库,JDBC连接数据库操作流程详细介绍

前言&#xff1a; 在学完 MySQL 和 Java 后&#xff0c;我们通常会尝试使用 Java编译器 连接 MySQL数据库&#xff0c;从而达到使用编译器来操作数据库的效果。连接的这个过程会用 JDBC 相关知识&#xff0c;因此我把 JDBC 包的下载及导入流程&#xff0c;以及 JDBC 的使用流程…

Arduino驱动L298N控制直流电机的正反转和调速

Arduino驱动L298N控制直流电机的正反转和调速 一、前言二、产品参数三、驱动直流电机三、接线图四、程序五、实验结果总结 一、前言 本模块使用ST公司的L298N作为主驱动芯片&#xff0c;具有驱动能力强&#xff0c;发热量低&#xff0c;抗干扰能力强的特点。LN&#xff12;&am…

Windows系统自带工具介绍

文章目录 1 Windows系统工具1.1 系统增强工具PowerToys1.1.1 简介1.1.2 使用 1.2 增强版任务管理器 Process Explorer1.2.1 简介1.2.2 使用 1.3 进程监视器 Process Monitor1.3.1 简介1.3.2 使用 1.4 数据恢复神器 Windows File Recovery1.4.1 简介1.4.2 使用 1.5 微软AI识图1.…

Acwing- 835. Trie字符串统计

什么是Trie&#xff1f;Trie是一种高效地存储和查找字符串集合的数据结构。 我想&#xff0c;看下图就明白了 hh~ 在本题中&#xff0c;我们将a-z映射为0-25&#xff0c;然后将其作为数组下标&#xff0c;便于处理。 idx为已使用的节点数量&#xff08;使用一个节点则idx&…

Go语言——【高质量编程 | 代码规范】

作者&#xff1a;非妃是公主 专栏&#xff1a;《Golang》 博客主页&#xff1a;https://blog.csdn.net/myf_666 个性签&#xff1a;顺境不惰&#xff0c;逆境不馁&#xff0c;以心制境&#xff0c;万事可成。——曾国藩 文章目录 一、高质量编程定义 二、代码规范1. 代码格式…

Scratch资料

Scratch软件是免费的、免费的、免费的。任何需要花钱才能下载Scratch软件的全是骗子。 1、什么是Scratch Scratch是麻省理工学院的“终身幼儿园团队”开发的一种图形化编程工具。是面向青少年的一款模块化&#xff0c;积木化、可视化的编程语言。 什么是模块化、积木化&…

箭牌家居首次亮相AWE展会,大秀智慧生活新提案

作者 | 曾响铃 文 | 响铃说 2023年作为全面贯彻党的二十大精神开局之年&#xff0c;同时也是后疫情时代的第一年&#xff0c;以科技创新驱动社会发展成为当下首要任务。 特别是科技强国战略的实施落地&#xff0c;对推动经济社会高质量发展有着不可或缺的作用。所谓需求产生…

线性表之单链表(详解)

&#x1f355;博客主页&#xff1a;️自信不孤单 &#x1f36c;文章专栏&#xff1a;数据结构与算法 &#x1f35a;代码仓库&#xff1a;破浪晓梦 &#x1f36d;欢迎关注&#xff1a;欢迎大家点赞收藏关注 文章目录 &#x1f365;前言&#x1f349;链表1. 链表的概念及结构2. 链…

肝一肝设计模式【二】-- 工厂模式

系列文章目录 肝一肝设计模式【一】-- 单例模式 传送门 肝一肝设计模式【二】-- 工厂模式 传送门 文章目录 系列文章目录前言一、简单工厂模式二、工厂方法模式三、抽象工厂模式写在最后 前言 在实际开发过程中&#xff0c;构建对象往往使用new的方式来构建&#xff0c;但随着…

Nginx搭建以及使用(linux)

1.概念 Nginx是一个高性能的HTTP和反向代理服务器&#xff0c;它可以用来处理静态文件&#xff0c;负载均衡&#xff0c;反向代理等功能。 Nginx的来历是这样的&#xff1a;它是由俄罗斯人伊戈尔赛索耶夫为Rambler.ru站点开发的&#xff0c;第一个公开版本发布于2004年…

java的构造方法

构造方法是 Java中最重要的方法&#xff0c;也是 Java语言中最基本的方法&#xff0c;它直接影响程序的结构。java中不允许重复使用构造方法&#xff0c;但可以重复使用构造函数。 1. Java中只有构造函数可以使用被调用方提供的参数&#xff08;如&#xff1a; int&#xff09;…

作为一名8年测试工程师,因为偷偷接私活被····

接私活 对程序员这个圈子来说是一个既公开又隐私的话题&#xff0c;不说全部&#xff0c;应该大多数程序员都有过想要接私活的想法&#xff0c;当然&#xff0c;也有部分得道成仙的不主张接私活。但是很少有人在公开场合讨论私活的问题&#xff0c;似乎都在避嫌。就跟有人下班后…

Linux进程通信——共享内存

共享内存 共享内存原理与概念函数接口的介绍与使用shmgetshmctlshmatshmdt通信 共享内存的特点共享内存的内核结构 system V消息队列&#xff08;了解&#xff09;system V——初识信号量信号量的预备概念理解信号量信号量的接口与结构 IPC资源的组织方式 共享内存 原理与概念…

在 Edge 中安装 Tampermonkey 的步骤

以下是在 Edge 中安装 Tampermonkey 的步骤&#xff1a; 目录 1. 打开 Edge 浏览器&#xff0c;进入 Tampermonkey 官网&#xff1a;[https://www.tampermonkey.net/](https://www.tampermonkey.net/)。2. 点击页面上方的“下载”按钮&#xff0c;选择“Microsoft Edge”选项。…

2.2.2 redis,memcached,nginx网络组件

课程目标&#xff1a; 1.网络模块要处理哪些事情 2.reactor是怎么处理这些事情的 3.reactor怎么封装 4.网络模块与业务逻辑的关系 5.怎么优化reactor? io函数 函数调用 都有两个作用&#xff1a;io检测 是否就绪 io操作 1. int clientfd accept(listenfd, &addr, &…

BigInteger和BigDecimal

BigInteger 当一个整数很大&#xff0c;大到long都无法保存&#xff0c;就可以使用BigInteger这个类 使用方法&#xff1a;new import java.math.BigInteger;//记得引包 BigInteger bigInteger new BigInteger("33333333333399999999999");//用字符串传入 System…

STM32物联网实战开发(6)——PWM驱动LED灯

PWM驱动LED灯 之前是使用标准库函数配置引脚输出PWM控制呼吸灯&#xff0c;因为开发板上的蜂鸣器是有源的&#xff0c;所以这次还是用来确定LED灯&#xff0c;这次使用的是HAL库&#xff0c;用CubeMX软件初始化PWM功能 PWM输出原理 Period&#xff1a;周期&#xff0c;单位是秒…

10个最流行的向量数据库【AI】

矢量数据库是一种将数据存储为高维向量的数据库&#xff0c;高维向量是特征或属性的数学表示。 每个向量都有一定数量的维度&#xff0c;范围从几十到几千不等&#xff0c;具体取决于数据的复杂性和粒度。 推荐&#xff1a;用 NSDT场景设计器 快速搭建3D场景。 矢量数据库&…