CodeAshen's blog CodeAshen's blog
首页
  • Spring Framework

    • 《剖析Spring5核心原理》
    • 《Spring源码轻松学》
  • Spring Boot

    • Spring Boot 2.0深度实践
  • Spring Cloud

    • Spring Cloud
    • Spring Cloud Alibaba
  • RabbitMQ
  • RocketMQ
  • Kafka
  • MySQL8.0详解
  • Redis从入门到高可用
  • Elastic Stack
  • 操作系统
  • 计算机网络
  • 数据结构与算法
  • 云原生
  • Devops
  • 前端
  • 实用工具
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
  • Reference
GitHub (opens new window)

CodeAshen

后端界的小学生
首页
  • Spring Framework

    • 《剖析Spring5核心原理》
    • 《Spring源码轻松学》
  • Spring Boot

    • Spring Boot 2.0深度实践
  • Spring Cloud

    • Spring Cloud
    • Spring Cloud Alibaba
  • RabbitMQ
  • RocketMQ
  • Kafka
  • MySQL8.0详解
  • Redis从入门到高可用
  • Elastic Stack
  • 操作系统
  • 计算机网络
  • 数据结构与算法
  • 云原生
  • Devops
  • 前端
  • 实用工具
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
  • Reference
GitHub (opens new window)
  • MySQL8.0详解与实战

  • MySQL面试指南

  • Redis从入门到高可用

  • Elastic-Stack

    • 第01章-Elasticsearch入门
    • 第02章-倒排索引与分词
      • 1.1 倒排索引定义
      • 1.2 倒排索引组成
      • 2.1 分词和分词器
      • 2.2 分词验证
      • 2.3 ES 内置分词器
      • 2.4 中文分词器
      • 2.5 分词器组成
        • 2.5.1 Character Filters
      • 2.5.2 Tokenizer
        • 2.5.3 Token Filters
      • 2.6 自定义分词
      • 2.7 分词使用说明
    • 第03章-Mapping设置
    • 第04章-Search API
    • 第05章-分布式特性介绍
    • 第06章-Search的运行机制
    • 第07章-聚合分析
    • 第08章-数据建模
    • 第09章-集群调优建议
  • 数据库
  • Elastic-Stack
CodeAshen
2023-02-10
目录

第02章-倒排索引与分词

# 一、倒排索引

# 1.1 倒排索引定义

正排索引:文档ld到文档内容、单词的关联关系

image-20201223002531840

倒排索引:单词到文档Id的关联关系

image-20201223002543128

查询包含“搜索引擎”的文档步骤:

  1. 通过倒排索引获得 搜索引擎 对应的文档id有1和3
  2. 通过正排索引查询1和3的完整内容
  3. 返回用户最终结果

# 1.2 倒排索引组成

倒排索引是搜索引擎的核心,主要包含两部分,单词词典 和 倒排列表

1. 单词词典(Term Dictionary):是记录倒排索引的重要组成

  • 记录所有文档的单词,一般都比较大
  • 记录单词到倒排列表的关联信息

单词字典的实现一般是用 B+Tree,下图排序采用拼音实现

image-20201223003245636

2. 倒排列表(Posting List) :记录了单词对应的文档集合,由 倒排索引项(Posting) 组成

倒排索引项主要包含如下信息:

  • 文档 id:用于获取原始信息
  • 单词频率(TF,Term Frequency):记录该单词在该文档中的出现次数,用于后续相关性算分
  • 位置(Position):记录单词在文档中的分词位置(多个),用于做词语搜索(Phrase Query)
  • 偏移(Offset):记录单词在文档的开始和结束位置,用于做高亮显示

以关键词 搜索引擎 为例,倒排列表构建如下图:

image-20201223004359116

单词词典对应倒排列表,每一个单词对应一个倒排索引项。单词字典与倒排列表整合在一起的结构如下:

image-20201223004504537

es存储的是一个json格式的文档,其中包含多个字段,每个字段会有自己的倒排索引,类似下图:

image-20201223004805824

# 二、分词

# 2.1 分词和分词器

分词 是指将文本转换成一系列单词的过程,也可以叫做文本分析,在 es 里面称为 Analysis

分词器 是 es 中专门处理分词的组件,英文为 Analyzer,它的组成如下:

  • Character Filters:针对原始文本进行处理,比如去除 html 特殊标记符
  • Tokenizer:将原始文本按照一定规则切分为单词
  • Token Filters:针对 tokenizer 处理的单词就行再加工,比如转小写、删除或新增等处理

分词器调用顺序如下图:

image-20201223234017523

# 2.2 分词验证

es 提供了一个测试分词的接口 _analyze,方便验证分词效果

  • 可以直接指定分词器进行测试

    image-20201223234252878

  • 可以直接指定索引中的字段进行测试

    image-20201223234507606

  • 可以自定义分词器进行测试

    image-20201223234645226

# 2.3 ES 内置分词器

ES 内置分词器有:Standard, Simple, Whitespace, Stop, Keyword, Pattern, Language

1、Standard Analyzer

默认分词器

  • 按词切分,支持多语言
  • 小写处理

image-20201223235202988

2、Simple Analyzer

  • 按照非字母切分
  • 小写处理

image-20201223235317950

3、Whitespace Analyzer

  • 按空格切分

image-20201223235505977

4、Stop Analyzer

Stop Word 指语气助词等修饰性的词语,比如the、an、的、这等等

  • 相比Simple Analyzer多了Stop Word处理

image-20201223235634051

5、Keyword Analyzer

  • 不分词,直接将输入作为一个单词输出

image-20201223235837595

6、Pattern Analyzer

  • 通过正则表达式自定义分割符
  • 默认是 \W+ ,即非字词的符号作为分隔符

image-20201223235935427

7、Language Analyzer

  • 提供了30+常见语言的分词器

# 2.4 中文分词器

常用分词系统

IK分词器

  • 实现中英文单词的切分,支持 ik_smart、ik_maxword 等模式
  • 可自定义词库,支持热更新分词词典
  • https://github.com/medcl/elasticsearch-analysis-ik

jieba

  • python 中最流行的分词系统,支持分词和词性标注
  • 支持繁体分词、自定义词典、并行分词等
  • https://github.com/sing1ee/elasticsearch-jieba-plugin

自然语言分词器

Hanlp

  • 由一系列模型与算法组成的 Java 工具包,目标是普及自然语言处理在生产环境中的应用
  • https://github.com/hankcs/HanLP

THULAC

  • THU Lexical Analyzer for Chinese,由清华大学自然语言处理与社会人文计算实验室研制推出的一套中文词法分析工具包,具有中文分词和词性标注功能
  • https://github.com/microbun/elasticsearch-thulac-plugin

# 2.5 分词器组成

当自带的分词无法满足需求时,可以自定义分词,通过自定义 Character Filters、 Tokenizer 和 Token Filters 实现

# 2.5.1 Character Filters

  • 在 Tokenizer 之前对原始文本进行处理,比如增加、删除或替换字符等
  • 自带的如下:
    • HTML Strip:去除 html 标签和转换 html 实体
    • Mapping:进行字符替换操作
    • Pattern Replace:进行正则匹配替换
  • 会影响后续 tokenizer 解析的 position 和 offset 信息

image-20201224000920272

# 2.5.2 Tokenizer

将原始文本按照一定规则切分为单词(term or token),自带的如下:

  • standard:按照单词进行分割
  • letter:按照非字符类进行分割
  • whitespace:按照空格进行分割
  • UAX URL Email:按照 standard 分割,但不会分割邮箱和 url
  • NGram 和 Edge NGram:连词分割
  • Path Hierarchy:按照文件路径进行切割

image-20201224001321927

# 2.5.3 Token Filters

对于 tokenizer 输出的单词(term)进行增加、删除、修改等操作,自带的如下:

  • lowercase:将所有 term 转换为小写
  • stop:删除 stop words
  • NGram 和 Edge NGram:连词分割
  • Synonym:添加近义词的 term

image-20201224001538986

# 2.6 自定义分词

自定义分词需要在索引的配置中设定,如下所示:

image-20201224002016287

自定义分词器 一

自定义分词 my_custom_analyzer 如下:

image-20201224002116550

测试结果:

image-20201224002309037

自定义分词器 二

这里使用将分词器的三个组成部分都进行了自定义

image-20201224002450077

测试结果:

image-20201224002659111

# 2.7 分词使用说明

分词有以下两个使用时机

  1. 索引时分词(Index Time)

    创建或更新文档时,会对相应的文档进行分词处理。索引时分词是通过配置 Index Mapping 中每个字段的 analyzer 属性实现的,不指定分词时,使用默认 standard

    image-20201224002839862

  2. 查询时分词(Search Time)

    指定查询时的分词器,对查询语句进行分词。指定方式有如下几种:

    • 查询的时候通过 analyzer 指定分词器(仅本次查询有效)
    • 通过 index mapping 设置 search analyzer 实现(创建索引时指定索引分词器和查询语句分词器)

    image-20201224002942705

一般不需要特别指定查询时分词器,直接使用索引时分词器即可,否则会出现无法匹配的情况。

另外还需要明确字段是否需要分词,不需要分词的字段就将 type 设置为 keyword,可以节省空间和提高写性能。

编辑 (opens new window)
上次更新: 2023/06/04, 12:34:19
第01章-Elasticsearch入门
第03章-Mapping设置

← 第01章-Elasticsearch入门 第03章-Mapping设置→

最近更新
01
第01章-RabbitMQ导学
02-10
02
第02章-入门RabbitMQ核心概念
02-10
03
第03章-RabbitMQ高级特性
02-10
更多文章>
Theme by Vdoing | Copyright © 2020-2023 CodeAshen | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式