ElasticSearch

1.ElasticSearch

1.概念

​ ElasticSearch是面向文档型数据库,一条数据在这里就是一个文档。为了方便理解,我们将ElasticSearch里存储文档数据和关系型数据库MySQL存储数据的概念进行了一个类比

ES里的Index可以看做一个库,而Type相当于表,Documents则相当于表的行

这里Types的概念已经被弱化,在ElasticSearch6.X中,一个index下已经只能包含一个type,ElasticSearch7.X中,Type的概念已经被移除了

2.倒排索引

  • 正排索引:是以文档对象的唯一ID作为索引,以文档内容作为记录的结构
  • 倒排索引:Inverted index,指的是将文档内容中的单词作为索引,将包含该词的文档ID作为记录的结构

假设目前有以下两个文档内容

苏州街维亚大厦 

桔子酒店苏州街店

其处理步骤如下

1、正排索引给每个文档进行编号,作为其唯一的标识

文档 id content
1 苏州街维亚大厦
2 桔子酒店苏州街店

2、生成倒排索引

  • 首先要对字段的内容进行分词,分词就是将一段连续的文本按照语义拆分为多个单词,这里两个文档包含的关键词有:苏州街、维亚大厦…
  • 然后按照单词来作为索引,对应的文档 id 建立一个链表,就能构成上述的倒排索引结构
Word 文档 id
苏州街 1,2
维亚大厦 1
维亚 1
桔子 2
酒店 2
大厦 1

有了倒排索引,能快速、灵活地实现各类搜索需求。整个搜索过程中我们不需要做任何文本的模糊匹配

例如,如果需要在上述两个文档中查询 苏州街桔子 ,可以通过分词后 苏州街 查到 1、2,通过 桔子 查到 2,然后再进行取交取并等操作得到最终结果

2.Es常用指令

创建索引

获取指定索引

获取所有索引

文档创建(相当于创建数据库的行)

文档创建(指定id)

查询所有索引

3.分词器概念

3.1.Analysis

文本分析是把全文本转换一系列单词(term/token)的过程,也叫分词。Analysis是通过Analyzer来实现的。当一个文档被索引时,每个Field都可能会创建一个倒排索引(Mapping可以设置不索引该Field)

倒排索引的过程就是将文档通过Analyzer分成一个一个的Term,每一个Term都指向包含这个Term的文档集合

当查询query时,Elasticsearch会根据搜索类型决定是否对query进行analyze,然后和倒排索引中的term进行相关性查询,匹配相应的文档

3.2.Analyzer

分析器(analyzer)都由三种构件块组成的:character filterstokenizerstoken filters

1)character filters 字符过滤器

在一段文本进行分词之前,先进行预处理,比如说最常见的就是,过滤html标签(hello --> hello),& --> and(I&you --> I and you)

2)tokenizer 分词器

tokenizer 接收字符流,分成多个token(通常是一个个的单词),然后输出一个token序列。例如,whitespace tokenizer按空格切分字符序列

输入

"Quick brown fox!"

输出

[Quick, brown, fox!]

特别声明一下:token还不能和单词、term对等,fox!是一个很好的子,fox!是一个token,但是不是一个单词,也不算一个term。

tokenizer 还会记录单词的位置信息(可用于紧邻查询)和每个单词首尾字母在字符串中的位置(主要用于高亮搜索)

英文分词可以根据空格将单词分开,中文分词比较复杂,可以采用机器学习算法来分词

Token 是指在文本分析过程中由分词器生成的最小单元它是对原始文本进行处理后的中间产物,代表文本的一部分(通常是一个单词或短语)
生成 token 的过程包括字符过滤分词和词条过滤

Elasticsearch is a distributed, RESTful search and analytics engine.

经过标准分析器处理,这段文本可能会生成如下 tokens:

"Elasticsearch"
"is"
"a"
"distributed"
"RESTful"
"search"
"and"
"analytics"
"engine"

这些 tokens 是分词器生成的中间产物,并未被实际存储在索引中,而是用于创建倒排索引
Term 是指实际存储在倒排索引中的词条它是从 token 转换而来的,并且经过所有必要的处理和规范化过程term 是搜索和索引的基础单元,存储在倒排索引中,用于高效地执行查询

基于上面的 tokens,假设分析器将所有单词转换为小写,并删除停用词(如 "is""a"),则存储在倒排索引中的 terms 可能是:

"elasticsearch"
"distributed"
"restful"
"search"
"and"
"analytics"
"engine"

这些 terms 是实际存储在倒排索引中的词条,用于在查询时快速查找匹配的文档

token和term的区别

  • Token 是分词器生成的中间结果,用于进一步处理
  • Term 是经过处理和规范化后的最终结果,存储在倒排索引中

存储位置

  • Token 不会直接存储,而是在分析过程中产生和使用
  • Term 被存储在倒排索引中,是索引和查询的基础

用途

  • Token 是文本分析和处理的中间产物,主要用于创建 terms
  • Term 是实际用于搜索和索引的词条
3)Token filters Token过滤器

文本经过Tokenizer之后,输出一个token序列。Token Filter用于对Tokenizer输出的序列做修改(eg.单词的大小写转换)、删除(eg.删除停用词)、增加(eg.增加同义词)等动作。(例将“Quick”转为小写),去掉词(例如停用词像“a”、“and”、“the”等等),或者增加词(例如同义词像“jump”和“leap”)

三者顺序Character Filters -> Tokenizer -> Token Filter

三者个数analyzer = CharFilters(0个或多个) + Tokenizer(恰好一个) + TokenFilters(0个或多个)

4.Es内置分词器

Elastic 默认支持九种不同的分词模式

1.stardard

过滤标点符号

在这里插入图片描述

2.simple

过滤标点符号和数字,只剩下字母了

在这里插入图片描述

3.whitespace

空格分词,不过滤内容

在这里插入图片描述

4.stop

过滤标点符号,数字,过滤语气词,停顿词

在这里插入图片描述

5.keyword

将内容作为一个整体,不做任何处理,所以这也是为什么keyword 用于精准匹配

在这里插入图片描述

6.patter

(正则匹配,参考java的正则匹配规则) 在该栗子中,只过滤数字

在这里插入图片描述

7.fingerprint

转小写 去重 过滤停止词,排序

在这里插入图片描述

5.创建索引时设置分词器

PUT new_index
{
	"settings": {
		"analysis": {
			"analyzer": {
				"std_folded": {
					"type": "custom",
					"tokenizer": "standard",
					"filter": [
						"lowercase",
						"asciifolding"
					]
				}
			}
		}
	},
	"mappings": {
		"properties": {
			"title": {
				"type": "text",
				"analyzer": "std_folded" #指定分词器
			},
			"content": {
				"type": "text",
				"analyzer": "whitespace" #指定分词器
			}
		}
	}
}

5.2.配置

标准分析器接受下列参数:

  • max_token_length : 最大token长度,默认255
  • stopwords : 预定义的停止词列表,如_english_或 包含停止词列表的数组,默认是 _none_
  • stopwords_path : 包含停止词的文件路径
PUT new_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_english_analyzer": {
          "type": "standard",       #设置分词器为standard
          "max_token_length": 5,    #设置分词最大为5
          "stopwords": "_english_"  #设置过滤词
        }
      }
    }
  }
}

6.中文分词

中文的分词器现在大家比较推荐的就是 IK分词器,当然也有些其它的比如 smartCNHanLP

6.1.IK分词器安装

开源分词器 Ik 的github:https://github.com/medcl/elasticsearch-analysis-ik

注意 IK分词器的版本要你安装ES的版本一致,我这边是7.1.0那么就在github找到对应版本,然后启动命令

./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.1.0/elasticsearch-analysis-ik-7.1.0.zip

运行结果:

img

注意 安装完插件后需重启Es,才能生效

6.2.IK使用

IK有两种颗粒度的拆分:

ik_smart: 粗粒度的拆分

ik_max_word: 细粒度的拆分

1) ik_smart 拆分

GET /_analyze
{
  "text":"中华人民共和国国徽",
  "analyzer":"ik_smart"
}

运行结果:

img

GET /_analyze 
{  
    "text":"中华人民共和国国徽",
    "analyzer":"ik_max_word" 
}

运行结果:

img

7.操作索引库

1) mapping属性

  • type:字段数据类型,常见的简单类型又:
    • 字符串:text(可分词的文本),keyword(精确值,例如:品牌,国家,ipizhi)
    • 数值:long,integer,short,byte,double,dloat
    • 布尔:boolean
    • 日期:date
    • 对象:object
    • image-20240624174751815
  • index:是否创建索引,默认为trueimage-20240624162129112

2) 索引库的CRUD

a.查看
GET /索引库名称
b.新增
PUT /索引库名称/_mapping
{
	"properties": {
		"新字段名": {
			"type": "integer"
		}
	}
}
c.修改

理论上不允许修改原有已经存在的索引库,因为mapping映射已经定义好,ES基于这些映射去创建倒排索引,若修改会导致倒排索引失效

但是可以添加新的字段,语法如下:

PUT /索引库名称/_mapping
{
	"properties": {
		"新字段名": {
			"type": "integer"
		}
	}
}
d.删除
DELETE /索引库名称

3) 文档的CRUD

a.查询DSL
GET /索引库名称/_doc/文档id
b.新增DSL
POST /索引库名/_doc/文档id    ----    这个id需要自己指定,否则系统随机生成
{
	"字段1": "值1",
	"字段2": "值2",
	"字段3": {
		"子属性1": "值3",
		"子属性2": "值4"
	},
}
c.编辑DSL

方式一:全量修改,会删除旧文档,添加新文档

PUT /索引库名/_doc/文档id   ---   id不存在就是新增,id存在就是修改
{
	"字段1": "值1",
	"字段2": "值2",
}

方式二:增量修改,修改指定字段值

POST /索引库名/update/1
{
	"字段1":"值1"
}
d.删除DSL
DELETE /索引库名称/_doc/文档id

image-20240624175052566

posted @   zhangyf1121  阅读(53)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· winform 绘制太阳,地球,月球 运作规律
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示