15_Elasticsearch 内部原理详细解析(下篇)
本文章收录于【Elasticsearch 系列】,将详细的讲解 Elasticsearch 整个大体系,包括但不限于ELK讲解、ES调优、海量数据处理等
一、什么是mapping
自动或手动为index中的type建立的一种数据结构和相关配置,简称为mapping。我们以下面的例子来说明什么是mapping。
插入几条数据,让es自动为我们建立一个索引
PUT /article/_doc/1
{
"post_date": "2017-01-01",
"title": "my first article",
"content": "this is my fi rst article in this website",
"author_id": 11400
}
我们可以通过 GET article/_mapping 命令来查看es自动建立的mapping,从下图可以看出es会根据字段值的不同会给字段设置不同的值
dynamic mapping,自动为我们建立index,以及对应的mapping,mapping中包含了每个field对应的数据类型,以及如何分词等
当然我们也可以手动在创建数据之前,先创建index以及对应的mapping
二、精确匹配与全文搜索的对比分析
1、精确匹配(exact value)
Elasticsearch中的数据可以大致分为两种类型:精准匹配及全文文本。
精准匹配是确定的,正如它的名字一样。精准匹配“Foo”和“foo”就并不相同。2021 和2021-09-15也不相同。
比如有个字段的值是2022-01-01,当通过精准匹配(exact value)搜索的时候,必须输入2022-01-01,才能搜索出来,如果你输入一个01,是搜索不出来的。
2、全文检索(full text)
全文文本从另一个角度来说是文本化的数据(常常以人类的语言书写),比如一篇推文(Twitter的文章)或邮件正文。
全文文本(full text)就不是说单纯的只是匹配完整的一个值,而是可以对值进行拆分词语后(分词)进行匹配,也可以通过缩写、时态、大小写、同义词等进行匹配。
比如:
(1)缩写 vs. 全程:cn vs china
(2)格式转化:like liked likes
(3)大小写:Tom vs tom
(4)同义词:like vs love
2017-01-01,2017 01 01,搜索2017,或者01,都可以搜索出来
china,搜索cn,也可以将china搜索出来
likes,搜索like,也可以将likes搜索出来
Tom,搜索tom,也可以将Tom搜索出来
like,搜索love,同义词,也可以将like搜索出来
三、倒排索引原理理解
假如我们有两个文档,他们分别是
doc1:I really liked my small dogs, and I think my mom also liked them.
doc2:He never liked any dogs, so I hope that my mom will not expect me to liked him.
我们来进行模拟分词以及倒排索引的建立。建立倒排索引的时候,会执行一个操作(normalization)。也就是说对拆分出的各个单词进行相应的处理,以提升后面搜索的时候能够搜索到相关联的文档的概率。
normalization简单来说就是在建立倒排索引时进行时态的转换,单复数的转换,同义词的转换,大小写的转换。比如:mom —> mother,liked —> like,small —> little,dogs —> dog。
建立倒排索引,加入normalization
当使用mother liked little dog搜索时,会先进行分词,然后进行normalization,就会把mother 转成 mom、like-->like、little--> little、dog-->dog。
搜索结果:doc1和doc2都会搜索出来
四、分词器的内部组成到底是什么,以及内置分词器的介绍
1、什么是分词器
分词器是Elasticsearch中很重要的一个组件,用来将一段文本分析成一个一个的词,Elasticsearch再根据这些词去做倒排索引。主要功能是做切分词语和normalization(提升recall召回率)
比如给你一段句子,然后将这段句子拆分成一个一个的单个的单词,同时对每个单词进行normalization(时态转换,单复数转换),分词器
recall召回率:搜索的时候,增加能够搜索到的结果的数量
2、分词器内部主要组成部分
分词器主要由三个部门组成:字符过滤器(character filter)、分词器(tokenizer)、token filter
-
character filter:在一段文本进行分词之前,先进行预处理。比如说最常见的就是,过滤html标签(<span>hello<span> 转换成 hello),& 转换成 and(I&you 转换成 I and you);
-
tokenizer:进行分词处置。比如hello you and me 进行分词之后 hello, you, and, me
-
token filter:进行normalization相关的一些操作。比如dogs转换成dog、liked转换成like、Tom转换成tom、a/the/an这种无意义的停用词直接干掉、mother转换成mom、small转换成little。
分词器非常重要,它能够将一段文本进行各种处理,最后处理好的结果才会拿去建立倒排索引。
2、elasticsearch内置分词器介绍
-
standard analyzer:标准分词器,是Elasticsearch中默认的分词器,可以拆分英文单词,大写字母统一转换成小写。
-
simple analyzer:按非字母的字符分词,例如:数字、标点符号、特殊字符等,会去掉非字母的词,大写字母统一转换成小写。
-
whitespace analyzer:简单按照空格进行分词,相当于按照空格split了一下,大写字母不会转换成小写。
-
stop analyzer:会去掉无意义的词,例如:the、a、an 等,大写字母统一转换成小写。
-
keyword analyzer:不拆分,整个文本当作一个词。
elasticsearch 中默认使用的分词器为standard。
下面用一个例子来说明在各个分词器中的表现
例子语句:Set the shape to semi-transparent by calling set_trans(5)
在各种分词器中的表现为
standard analyzer:set, the, shape, to, semi, transparent, by, calling, set_trans, 5
simple analyzer:set, the, shape, to, semi, transparent, by, calling, set, trans
whitespace analyzer:Set, the, shape, to, semi-transparent, by, calling, set_trans(5)
language analyzer(特定的语言的分词器,比如说,英语分词器):set, shape, semi, transpar, call, set_tran, 5
五、query string的分词器
1、query string分词
query string必须和index建立时相同的analyzer进行分词,其对exact value和full text是区别对待的
比如我们有一个document,其中有一个field,包含的value是:hello you and me,建立倒排索引。我们要搜索这个document对应的index,搜索文本是hell me,这个搜索文本就是query string。
query string默认情况下es会使用它对应的field建立倒排索引时相同的分词器去进行分词,进行分词和normalization。只有这样才能实现正确的搜索
比如我们建立倒排索引的时候,将dogs --> dog,结果你搜索的时候,还是一个dogs,那不就搜索不到了吗?所以搜索的时候,那个dogs也必须变成dog才行。才能搜索到。
不同类型的field,可能有的就是full text,有的就是exact value
六、mapping 元数据详细讲解
1、什么是mapping
mapping是定义文档及其包含的字段如何存储和索引的过程。
mapping就是index的元数据,每个index都有一个自己的mapping,决定了数据类型,建立倒排索引的行为,还有进行搜索的行为例如等。
可以使用映射(mapping)来定义哪些字符串字段应被视为全文字段,哪些字段包含数字、日期或地理位置以及日期值的格式,还可以自定义规则来控制动态添加字段的映射。
ES的mapping类似于静态语言中的数据类型:声明一个变量为int类型的变量,以后这个变量都只能存储int类型的数据。一个number类型的mapping字段只能存储number类型的数据。
同语言的数据类型相比,mapping还有一些其他的含义,mapping不仅告诉ES一个field中是什么类型的值, 它还告诉ES如何索引数据以及数据是否能被搜索到。
当你的查询没有返回相应的数据,你的mapping很有可能有问题。当你拿不准的时候,直接检查你的mapping。
当我们向elasticsearch中插入一条数据时,es内部流程如下:
(1)往es里面直接插入数据,es会自动建立索引,同时建立type以及对应的mapping
(2)mapping中就自动定义了每个field的数据类型
(3)不同的数据类型(比如说text和date),可能有的是exact value,有的是full text
(4)exact value,在建立倒排索引的时候,分词的时候,是将整个值一起作为一个关键词建立到倒排索引中的;full text,会经历各种各样的处理,分词,normaliztion(时态转换,同义词转换,大小写转换),才会建立到倒排索引中
(5)同时呢,exact value和full text类型的field就决定了,在一个搜索过来的时候,对exact value field或者是full text field进行搜索的行为也是不一样的,会跟建立倒排索引的行为保持一致;比如说exact value搜索的时候,就是直接按照整个值进行匹配,full text query string,也会进行分词和normalization再去倒排索引中去搜索
(6)可以用es的dynamic mapping,让其自动建立mapping,包括自动设置数据类型;也可以提前手动创建index和type的mapping,自己对各个field进行设置,包括数据类型,包括索引行为,包括分词器,等等
2、mapping的核心数据类型以及dynamic mapping
(1)、核心的数据类型
mapping的核心数据类型分为:
简单类型:string、byte、short、integer、long、float、double、boolean、date;
对象类型:一种支持 JSON 分层性质的类型。例如 object或nested。
特殊类型:如geo_point, geo_shape, 或completion
(2)动态映射(dynamic mapping)
当我们插入一条数据时,如果这个索引在es中存在,es则会根据相应的规则帮我们动态映射到对应的mapping数据类型。
比如true或false会映射成boolean类型,123会映射成long类型,123.45映射成double类型,2017-01-01映射成date类型,"hello world" 映射成string(text)类型
(3)查看索引的mapping结构
GET article/_mapping
3、手动建立和修改mapping以及定制string类型数据是否分词
(1)如何建立索引
允许分词:analyzed
不允许分词:not_analyzed
不能被索引和分词:no
只能创建index时手动建立mapping,或者新增field mapping,但是不能update field mapping
创建索引
PUT /article
{
"mappings": {
"properties": {
"author_id": {
"type": "long"
},
"title": {
"type": "text",
"analyzer": "english"
},
"content": {
"type": "text"
},
"post_date": {
"type": "date"
}
}
}
}
(2)对mapping的各种操作
但是不能够修改mapping,修改mapping时会报错:index [article/F4pFl4TdQASTSN2y-kkgEA] already exists
但是可以新增字段,然后设置对应的数据类型
#新增mapping字段映射
PUT /article/_mapping
{
"properties": {
"createName": {
"type": "keyword"
}
}
}
查看索引中所有字段的mapping映射
GET /article/_mapping
查看索引单个字段的mapping映射
GET /article/_mapping/field/createName
(3)mapping复杂数据类型以及object类型
a、多值字段:multivalue field
{ "tags": [ "tag1", "tag2" ]}
建立索引时与string是一样的,数据类型不能混
b、空字段:empty field
null,[],[null]
c、对象字段:object field
比如如下index中,address就是个对象字段(object类型)
PUT /company/employee/1
{
"address": {
"country": "china",
"province": "guangdong",
"city": "guangzhou"
},
"name": "jack",
"age": 27,
"join_date": "2017-01-01"
}
< END >
本文章收录于【Elasticsearch 系列】,将详细的讲解 Elasticsearch 整个大体系,包括但不限于ELK讲解、ES调优、海量数据处理等