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常用指令
创建索引
- GET/PUT:http://127.0.0.1:9200/document
获取指定索引
获取所有索引
文档创建(相当于创建数据库的行)
- GET/POST:http://127.0.0.1:9200/document/_doc
文档创建(指定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 filters
, tokenizers
, token 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分词器
,当然也有些其它的比如 smartCN、HanLP
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
运行结果:
注意
安装完插件后需重启Es,才能生效
6.2.IK使用
IK有两种颗粒度的拆分:
ik_smart
: 粗粒度的拆分
ik_max_word
: 细粒度的拆分
1) ik_smart 拆分
GET /_analyze
{
"text":"中华人民共和国国徽",
"analyzer":"ik_smart"
}
运行结果:
GET /_analyze
{
"text":"中华人民共和国国徽",
"analyzer":"ik_max_word"
}
运行结果:
7.操作索引库
1) mapping属性
- type:字段数据类型,常见的简单类型又:
- 字符串:text(可分词的文本),keyword(精确值,例如:品牌,国家,ipizhi)
- 数值:long,integer,short,byte,double,dloat
- 布尔:boolean
- 日期:date
- 对象:object
- index:是否创建索引,默认为true
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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· winform 绘制太阳,地球,月球 运作规律
· 上周热点回顾(3.3-3.9)