《Elastic Stack 实战手册》——三、产品能力——3.4.入门篇——3.4.2.Elasticsearch基础应用——3.4.2.1.inverted index,doc_values,store及source(1) /article/1231138
禁用索引
?
默认情况下,Elasticsearch 文档每个字段都会被索引。如果某些字段不需要支持查询,可以在映射中配置 "index": false ,减少存储空间占用,并且提升写入速度。
?
例如,文章的标题、正文、发布时间字段,需要创建索引,文章的 url 字段不需要被索引,创建索引映射时可以按以下方式禁用它:
PUT news
{
"settings": {
"number_of_shards": 5,
"number_of_replicas": 1
},
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word"
},
"content": {
"type": "text",
"analyzer": "ik_max_word"
},
"createtime": {
"type": "date"
},
"url": {
"type": "keyword",
"index": false
}
}
}
}
文档值
?
在 Elasticsearch 中,Doc Values 是一种列式存储结构。Doc Values 默认对所有字段启用,除了 text 和 annotated_text 类型字段。
?
Doc Values 是在索引时创建的,当字段索引时,Elasticsearch 为了能够快速检索,会把字段的值加入倒排索引中,同时它也会存储该字段的 Doc Values。
?
Elasticsearch 中的 Doc Values 常被应用到以下场景:
?
l?对一个字段进行排序
l?对一个字段进行聚合
l?某些过滤,比如地理位置过滤
l?某些与字段相关的脚本计算
l?使用 docvalue_fields 返回搜索结果部分字段值
?
因为文档值被序列化到磁盘,可以依靠操作系统的帮助来快速访问。当数据集远小于节点的可用内存,操作系统会自动将所有的 Doc Values 保存在内存中,使得其读写十分高速;当其远大于可用内存,操作系统会自动把 Doc Values 加载到系统的页缓存中,从而避免了 JVM 堆内存溢出异常。
?
列式存储的压缩
?
Doc Values 本质上是一个序列化的列式存储,适用于聚合、排序、脚本等操作。这种存储方式
也非常便于压缩,特别是数字类型,这样可以节约磁盘空间,并且提高访问速度。
?
来看一组数字类型的 Doc Values,了解它如何压缩数据:

按列布局意味着我们有一个连续的数据块:[100,1000,1500,1200,300,1900,4200]。
?
因为我们已经知道他们都是数字,而不是像文档或行中看到的异构集合,所以我们可以使用统一的偏移来将他们紧紧排列。
?
而且,针对这样的数字有很多种压缩技巧。你会注意到这里每个数字都是 100 的倍数,Doc
Values 会检测一个段里面的所有数值,并使用一个最大公约数,方便做进一步的数据压缩。
?
如果我们保存100 作为此段的除数,我们可以对每个数字都除以100,然后得到: [1,10,15,12,3,19,42]。
?
现在这些数字变小了,只需要很少的位就可以存储下,也减少了磁盘存放的大小。Doc Values 在压缩过程中使用如下技巧,它会按依次检测以下压缩模式:
?
1、如果所有的数值各不相同或缺失,设置一个标记并记录这些值。
2、如果这些值小于 256,将使用一个简单的编码表。
3、如果这些值大于 256,检测是否存在一个最大公约数。
4、如果没有存在最大公约数,从最小的数值开始,统一计算偏移量进行编码。
?
你会发现这些压缩模式不是传统的通用压缩算法,比如 DEFLATE 或者 LZ4。因为列式存储的结构是严格且良好定义的,我们可以通过使用专门的模式来达到,比通用压缩算法(如 LZ4)更高的压缩效果。
?
《Elastic Stack 实战手册》——三、产品能力——3.4.入门篇——3.4.2.Elasticsearch基础应用——3.4.2.1.inverted index,doc_values,store及source(3) /article/1231136