Elasticsearch 篇之倒排索引与分词

Elasticsearch 篇之倒排索引与分词

书的目录与索引

正排索引

  • 文档Id到文档内容、单词的关联关系
文档Id 文档内容
1 elasticsearch是最流行的搜索引擎
2 php是世界上最好的语言
3 搜索引擎是如何诞生的

倒排索引

  • 单词到文档id的关联关系
单词 文档ID列表
elasticsearch 1
流行 2
搜索引擎 1,3
php 2
1,2,3

正排与倒排索引简介

在这里插入图片描述
查询包含"搜素引擎"的文档

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

倒排索引详解

倒排索引组成

  • 单词词典(Term Dictionary)是倒排索引的重要组成
    • 记录所有文档的单词,一般都比较大
    • 记录单词到倒排列表的关联信息
    • 单词字典的实现一般是用B+ Tree,示例如下图: 在这里插入图片描述
  • 倒排列表(Posting List)记录了单词对应的文档集合,由倒排索引项(Posting)组成
    • 倒排索引项(Posting)主要包含如下信息:
      • 文档Id,用于获取原始信息
      • 单词频率(TF,Term Frequency):记录改单词在该文档中出现次数,用于后继相关性算分
      • 位置(Position):记录单词在文档中的分词位置(多个),用于做词语搜索(Phrase Query)
      • 偏移(Offser):记录单词在文档的开始和结束位置,用于做高亮显示
    • 以"搜索引擎"为例
      在这里插入图片描述
    • 倒排索引与倒排列表整合在一起的结构如下:
      在这里插入图片描述
    • es存储的是一个json格式的文档,其中包含多个字段,每个字段会有自己的倒排索引。
      在这里插入图片描述

分词介绍

分词是指将文本转换成一系列单词(term or token)的过程,也可以叫做文本分析,在es里面成为Analysis,如下图所示:

  • 文本:elasticsearch是最流行的搜索引擎
  • 分词结果:elasticsearch 流行 搜索引擎

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

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

在这里插入图片描述

analyze_api

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

  • 可以直接指定analyze进行测试
    在这里插入图片描述
	POST _analyze
	{
	  "analyzer": "standard",
	  "text": "hello word"
	}

在这里插入图片描述

	POST _analyze
	{
	  "analyzer": "standard",
	  "filter": ["lowercase"],
	  "text": "Hello Word"
	}

在这里插入图片描述

  • 可以直接指定索引中的字段进行测试
  • 可以自定义分词器进行测试

自带分词器

es自带如下的分词器

  • Standard
    • 默认分词器
    • 其组成如图,特性为:
      • 按词切分,支持多语言
      • 小写处理
        在这里插入图片描述
  • Simple
    • 其组成如图,特性为:
      • 按照非字母切分
      • 小写处理
        在这里插入图片描述
	POST _analyze
	{
	  "analyzer": "simple",
	  "filter": ["lowercase"],
	  "text": "Hello Word 1"
	}

在这里插入图片描述

  • Whitespace
    • 其组成如图,特性为:
      • 按照空格切分
        在这里插入图片描述
	POST _analyze
	{
	  "analyzer": "whitespace",
	  "text": "Hello Word 1 啊"
	}

在这里插入图片描述

  • Stop
    • Stop Word指语气助词等修饰性的词语,比如the、an、的、这等
      • 其组成如图,特性为:
      • 相比Simple多了Stop Word处理
        在这里插入图片描述
	POST _analyze
	{
	  "analyzer": "stop",
	  "text": "Hello or and Word 1 啊"
	}

在这里插入图片描述

  • Keyword
    • 其组成如图,特性为:
      • 不分词,直接将输入作为一个单词输出
        在这里插入图片描述
	POST _analyze
	{
	  "analyzer": "keyword",
	  "text": "Hello or and Word 1 啊"
	}

在这里插入图片描述

  • Pattern
  • 其组成如图,特性为:
    • 通过正则表达式自定义分隔符
    • 默认是\W+,即非字词的符号作为分隔符
      在这里插入图片描述
	POST _analyze
	{
	  "analyzer": "pattern",
	  "text": "Hello-Word day's"
	}

在这里插入图片描述

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

中文分词

  • 中文分词指的是将一个汉字序列切分成一个一个单独的词。在英文中,单词之间是以空格作为自然分界符,汉字中词没有一个形式上的分界符。
  • 上下文不用,分词结果迥异,比如交叉歧义问题,比如下面两种分词都合理
    • 乒乓球拍/卖/完了
    • 乒乓球/拍卖/完了
  • 常见分词系统
    • IK
      • 实现中英文单词的切分,支持ik_smart、ik_maxword模式
      • 可自定义词库,支持热更新分词词典
      • https://github.com/medcl/elasticsearch-analysis-ik
    • jieba
      • python中最流行的分词系统,支持分词和词性标注
      • 支持繁体分词、自定义词典、并行分词等
      • https://github.com/sing1ee/elasticsearch-jieba-plugin

在这里插入图片描述

自定义分词

当自带的分词无法满足需求的时候,就需要自定义分词。
自定义分词就是通过Character Filters、Tokenizer和Token Filter实现。

自定义分词之CharacterFilter

在Tokenizer之前对原始文本进行处理,比如增加、删除或替换的字符等。
es自带的如下:

  • html_strip:去除html标签和转换html字体
  • Mapping:进行字符串替换
  • Pattern Replace:进行正则匹配替换
  • 由于它是第一步,所以它的结果会影响Tokenizer的position和offset的结果
POST _analyze
{
  "tokenizer": "keyword",
  "char_filter": ["html_strip"],
  "text": "<p>I&apos;m so <b>happy</b>!</p>"
}

在这里插入图片描述

自定义分词之Tokenizer

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

  • standard:按照单词切割
  • letter:按照非字符切割
  • whitespace:按照空格切割
  • UAX URL Eamil 按照standard切割,但不会分割邮箱和url
  • NGram和Edge NGram:连词分割(例如搜索时根据输入提示相关内容)
  • path_hierarchy:按照文件路径进行分割
POST _analyze
{
  "tokenizer": "path_hierarchy",
  "text": "/one/two/three"
}

在这里插入图片描述

自定义分词之 TokenFilter

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

  • lowercase:将所有term转化为小写
  • stop:删除stop word
  • NGram和Edge NGram:连词分割
  • Synonym:添加近义词的term
POST _analyze
{
  "text": "a Hello,word",
  "tokenizer": "standard",
  "filter": [
    "stop",
    "lowercase",
    {
      "type": "ngram",
      "min_gram": 4,
      "max_gram": 4
    }
  ]
}

在这里插入图片描述

自定义分词

在这里插入图片描述

PUT test_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_custom_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "char_filter": ["html_strip"],
          "filter": ["lowercase","asciifolding"]
        }
      }
    }
  }
}
POST test_index/_analyze
{
  "analyzer": "my_custom_analyzer",
  "text": "Is this <b>a box</b>"
}

在这里插入图片描述
在这里插入图片描述

分词使用说明

分词一般会在以下的情况下使用:

  • 创建或更新文档的时候,会对相应的文档进行分词处理。
  • 查询时,会对查询语句进行分词

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

发布了77 篇原创文章 · 获赞 33 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_39337886/article/details/103857934