ElasticSearch-倒排索引 文档映射
- 倒排索引
- 文档映射
- 已有字段的Mapping修改
- 常用Mapping参数配置
- Index Template
- Dynamic Template
倒排索引
-
当数据写入 ES 时,数据将会通过 分词 被切分为不同的 term,ES 将 term 与其对应的文档列表建立一种映射关系,这种结构就是 倒排索引
-
为了进一步提升索引的效率,ES 在 term 的基础上利用 term 的前缀或者后缀构建了 term index, 用于对 term 本身进行索引
-
当我们去搜索某个关键词时,ES 首先根据它的前缀或者后缀迅速缩小关键词的在 term dictionary 中的范围,大大减少了磁盘IO的次数
- 单词词典(Term Dictionary) :记录所有文档的单词,记录单词到倒排列表的关联关系
- 倒排列表(Posting List):记录了单词对应的文档结合,由倒排索引项组成
- 倒排索引项(Posting):
- 文档ID
- 词频TF:该单词在文档中出现的次数,用于相关性评分
- 位置 (Position):单词在文档中分词的位置。用于短语搜索(match phrase query)
- 偏移 (Offset):记录单词的开始结束位置,实现高亮显示
-
Elasticsearch 的JSON文档中的每个字段,都有自己的倒排索引
-
可以指定对某些字段不做索引
- 优点︰节省存储空间
- 缺点: 字段无法被搜索
文档映射
- Mapping类似数据库中的schema的定义,作用如下
- 定义索引中的字段的名称
- 定义字段的数据类型,例如字符串,数字,布尔等
- 字段,倒排索引的相关配置 (Analyzer)
- ES中Mapping映射可以分为动态映射和静态映射
-
动态映射:不需要定义Mapping映射(即关系型数据库的表、字段等),在文档写入Elasticsearch时,会根据文档字段自动识别类型,这种机制称之为动态映射
- 动态映射(Dynamic Mapping)的机制,使得我们无需手动定义Mappings,Elasticsearch会自动根据文档信息,推算出字段的类型
- 但是有时候会推算的不对,例如地理位置信息
- 当类型如果设置不对时,会导致一些功能无法正常运行,例如Range查询
-
静态映射:事先定义好映射,包含文档的各字段类型、分词器等,这种方式称之为静态映射
-
已有字段的Mapping修改
- 后期更改Mapping的字段类型
-
新增加字段
- dynamic设为true时,一旦有新增字段的文档写入,Mapping也同时被更新
- dynamic设为false,Mapping 不会被更新,新增字段的数据无法被索引,但是信息会出现在_source中
- dynamic设置成strict (严格控制策略),文档写入失败,抛出异常
-
对已有字段,一旦已经有数据写入,就不再支持修改字段定义
- Lucene 实现的倒排索引,一旦生成后,就不允许修改
- 如果希望改变字段类型,可以利用 reindex API,重建索引
-
原因
- 如果修改了字段的数据类型,会导致已被索引的数据无法被搜索
- 但是如果是增加新的字段,就不会有这样的影响
-
- 对已有字段的mapping修改:实现索引的平滑过渡,并且是零停机
- 如果要推倒现有的映射, 你得重新建立一个静态索引
- 然后把之前索引里的数据导入到新的索引里
POST _reindex
- 删除原创建的索引
- 为新索引起个别名, 为原索引名
PUT /user2/_alias/user
PUT /user2
{"mappings":{
"properties":{"name":{"type":"text"}}}}
POST _reindex
{"source":{"index":"user"},
"dest":{"index":"user2"}}
DELETE /user
PUT /user2/_alias/user
常用Mapping参数配置
- index: 控制当前字段是否被索引,默认为true
- 如果设置为false,该字段不可被搜索
PUT /user
{"mappings": {
"properties": {
"name":{"type":"text","index":false}}}}
- 有四种不同基本的index options配置,控制倒排索引记录的内容
- docs : 记录doc id
- freqs:记录doc id 和term frequencies(词频)
- positions: 记录doc id / term frequencies / term position
- offsets: doc id / term frequencies / term posistion / character offsets
- text 类型默认记录 postions,其他默认为 docs
- 记录内容越多,占用存储空间越大
PUT /user
{"mappings":{
"properties": {
"name":{"type":"text","index_options":"offsets"}}}}
- null_value: 需要对Null值进行搜索,只有keyword类型支持设计Null_Value才行
PUT /user
{"mappings":{
"properties": {
"name":{"type":"keyword","null_value":"NULL"}}}}
- copy_to设置:将字段的数值拷贝到目标字段,满足一些特定的搜索需求
- copy_to的目标字段不出现在_source中
PUT /user
{"mappings":{
"properties":{
"name":{"type":"text","copy_to":"full_address"}}}}
Index Template
- Index Templates可以帮助你设定Mappings和Settings,并按照一定的规则,自动匹配到新创建的索引之上
- 模版仅在一个索引被新创建时,才会产生作用。修改模版不会影响已创建的索引
- 你可以设定多个索引模版,这些设置会被“merge”在一起
- 你可以指定“order”的数值,控制“merging”的过程
- 当一个索引被新创建时
- 应用Elasticsearch 默认的settings 和mappings
- 应用order数值低的lndex Template 中的设定
- 应用order高的 Index Template 中的设定,之前的设定会被覆盖
- 应用创建索引时,用户所指定的Settings和 Mappings,并覆盖之前模版中的设定
PUT /_template/template_default
{"index_patterns": ["*"],
"order": 0,
"version": 1,
"settings": {
"number_of_shards":1,
"number_of_replicas":1}}
Dynamic Template
- Dynamic Tempate定义在某个索引的Mapping中
PUT my_index
{"mappings":{
"dynamic_templates":[{
"strings_as_boolean":{
"match_mapping_type":"string",
"match":"is*",
"mapping":{"type":"boolean"}}}]}}