ElasticSearch 高级查询语法Query DSL实战

ES倒排索引
当数据写入 ES 时,数据将会通过 分词 被切分为不同的 term,ES 将 term 与其对应的文 档列表建立一种映射关系,这种结构就是 倒排索引。如下图所示:
ElasticSearch 高级查询语法Query DSL实战_第1张图片
为了进一步提升索引的效率,ES 在 term 的基础上利用 term 的前缀或者后缀构建了 term index, 用于对 term 本身进行索引,ES 实际的索引结构如下图所示:
ElasticSearch 高级查询语法Query DSL实战_第2张图片

这样当我们去搜索某个关键词时,ES 首先根据它的前缀或者后缀迅速缩小关键词的在 term dictionary 中的范围,大大减少了磁盘IO的次数。
        
单词词典(Term Dictionary) :记录所有文档的单词,记录单词到倒排列表的 关联关系
        常用字典数据结构:
         ElasticSearch 高级查询语法Query DSL实战_第3张图片

倒排列表(Posting List)-记录了单词对应的文档结合,由倒排索引项组成

倒排索引项(Posting):
        文档ID
        词频TF–该单词在文档中出现的次数,用于相关性评分
        位置(Position)-单词在文档中分词的位置。用于短语搜索 (match phrase query)
        偏移(Offset)-记录单词的开始结束位置,实现高亮显示

ElasticSearch 高级查询语法Query DSL实战_第4张图片

Elasticsearch 的JSON文档中的每个字段,都有自己的倒排索引。

可以指定对某些字段不做索引:
        优点︰节省存储空间
        缺点: 字段无法被搜索
文档映射Mapping
Mapping类似数据库中的schema的定义 ,作用如下:
        定义索引中的字段的名称
        定义字段的数据类型,例如字符串,数字,布尔等
        字段,倒排索引的相关配置(Analyzer)
ES中Mapping映射可以分为动态映射和静态映射

动态映射:
在关系数据库中,需要事先创建数据库,然后在该数据库下创建数据表,并创建表字段、类 型、长度、主键等,最后才能基于表插入数据。而Elasticsearch中不需要定义Mapping映 射(即关系型数据库的表、字段等), 在文档写入Elasticsearch时,会根据文档字段自动识 别类型,这种机制称之为动态映射。
静态映射:
静态映射是在Elasticsearch中也可以事先定义好映射,包含文档的各字段类型、分词器 等,这种方式称之为静态映射。动态映射(Dynamic Mapping)的机制,使得我们无需手动定Mappings,
Elasticsearch会自动根据文档信息,推算出字段的类型。但是有时候会推算的不对,例如地 理位置信息。 当类型如果设置不对时,会导致一些功能无法正常运行,例如Range查询
Dynamic Mapping类型自动识别:
ElasticSearch 高级查询语法Query DSL实战_第5张图片

示例
#删除原索引
 DELETE /user

 #创建文档(ES根据数据类型, 会自动创建映射)
 PUT /user/_doc/1
 {
 "name":"yanqiuxiang",
 "age":34,
 "address":"江西南昌"
 }

 #获取文档映射
 GET /user/_mapping

ElasticSearch 高级查询语法Query DSL实战_第6张图片

思考:能否后期更改Mapping的字段类型?

两种情况:
新增加字段
      1、  dynamic设为true时,一旦有新增字段的文档写入,Mapping 也同时被更新
        2、dynamic设为false,Mapping 不会被更新,新增字段的数据 无法被索引,但是信息会出现在 _source中
        3、dynamic设置成strict(严格控制策略),文档写入失败,抛出异常      
ElasticSearch 高级查询语法Query DSL实战_第7张图片   
对已有字段,一旦已经有数据写入,就不再支持修改字段定义
        Lucene 实现的倒排索引,一旦生成后,就不允许修改
         如果希望改变字段类型,可以利用 reindex API,重建索引
原因:
        如果修改了字段的数据类型,会导致已被索引的数据无法被搜索
        但是如果是增加新的字段,就不会有这样的影响
dynamic设置成strict,新增字段导致文档插入失败
PUT /user
{
	"mappings": {
		"dynamic": "strict",
		"properties": {
			"name": {
				"type": "text"
			},
			"address": {
				"type": "object",
				"dynamic": "true"
			}
		}
	}
}
ElasticSearch 高级查询语法Query DSL实战_第8张图片

修改dynamic后再次插入文档成功

#修改daynamic
 PUT /user/_mapping
 {
 "dynamic":true
 }
对已有字段的mapping修改
具体方法:
1)如果要推倒现有的映射, 你得重新建立一个静态索引
2)然后把之前索引里的数据导入到新的索引里
3)删除原创建的索引
4)为新索引起个别名, 为原索引名
PUT / user2 
{
	"mappings": {
		"properties": {
			"name": {
				"type": "text"
			},
			"address": {
				"type": "text",
				"analyzer": "ik_max_word"
			}
		}
	}
}

POST _reindex 
{
	"source": {
		"index": "user"
	},
	"dest": {
		"index": "user2"
	}
}

DELETE /user

PUT /user2/_alias/user

GET /user
注意: 通过这几个步骤就实现了索引的平滑过渡,并且是零停机
常用Mapping参数配置
        index: 控制当前字段是否被索引,默认为true。 如果设置为false,该字段不可被搜索
PUT /user 
{
	"mappings": {
		"properties": {
			"address": {
				"type": "text",
				"index": false
			},
			"age": {
				"type": "long"
			},
			"name": {
				"type": "text"
			}
		}
	}
}

ElasticSearch 高级查询语法Query DSL实战_第9张图片

有四种不同基本的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

你可能感兴趣的:(分布式框架,elasticsearch,大数据,搜索引擎)