Elasticsearch 倒排索引
底层原理
正排索引(doc values )VS 倒排索引:
概念:从广义来说,doc values 本质上是一个序列化的 列式存储 。列式存储 适用于聚合、排序、脚本等操作,所有的数字、地理坐标、日期、IP 和不分析( not_analyzed )字符类型都会默认开启。
特点:倒排索引的优势 在于查找包含某个项的文档,相反,如果用它确定哪些项是否存在单个文档里。
总结:全文搜索需要用倒排索引,而排序和聚合则需要使用 正排索引。
在Mappings中有两个相关配置
1 | doc_values:true/false |
1 | PUT /product |
1 | //当使用es自带的keyword时,它字段值是一个整体的精确匹配,并不会对字段值的内容进行分词 |
而
doc_values正排索引不支持text字段,那text字段怎么进行聚合操作呢?
1 | //当直接使用tags进行聚合操作,想要聚合tags中的分词后的terms词项,会报错 |
1 | Text fields are not optimised for operations that require per-document field data like aggregations and sorting, |
大概的意思是,必须要打开fielddata=true,然后将正排索引数据加载到内存中,才可以对分词的field执行聚合操作,而且会消耗很大的内存。
1 | //修改Mapping结构:开启tags字段 在使用聚合操作时使用 正排索引进行计算 |
这时候再次执行上文的tags的聚合操作,就不会报错了,那么fielddata和doc_values都是开启正排索引,他们之间有什么区别呢?
| 维度 | doc_values | fielddata |
|---|---|---|
| 创建时间 | index时创建 | 使用时动态创建 |
| 创建位置 | 磁盘 | 内存(jvm heap) |
| 优点 | 不占用内存空间 | 不占用磁盘空间 |
| 缺点 | 索引速度稍低 | 文档很多时,动态创建开销比较大,而且占内存 |
| 默认值 | true | false |
doc_values速度稍低这个是相对于fielddata方案的,其实仔细想想也可以理解。拿排序举例,相对于一个在磁盘排序,一个在内存排序。谁的速度快自然不用多说。
与 doc values 不同,fielddata 构建和管理 100% 在内存中,常驻于 JVM 内存堆。这意味着它本质上是不可扩展的。
fielddata可能会消耗大量的堆空间,尤其是在加载高基数(high cardinality)text字段时。一旦fielddata已加载到堆中,它将在该段的生命周期内保留。此外,加载fielddata是一个昂贵的过程,可能会导致用户遇到延迟命中。这就是默认情况下禁用fielddata的原因。
doc_values虽然速度稍慢,但doc_values的优势还是非常明显的。一个很显著的点就是他不会随着文档的增多引起OOM问题。正如前面说的,doc_values在磁盘创建排序和聚合所需的正排索引。这样我们就避免了在生产环境给ES设置一个很大的HEAP_SIZE,也使得JVM的GC更加高效,这个又为其它的操作带来了间接的好处。
1 | 1.当没有doc value的字段需要聚合时,需要打开fielddata,然后临时在内存中建立正排索引,fielddata的构建和管理发生在JVM heap中。 |


为什么不可以用倒排索引计算聚合?
对于聚合部分,我们需要找到匹配的doc里所有唯一的词项(term)。需要遍历每个doc获取所有trem词项,然后再一个个去倒排索引表中进行查找,是一个 n x m 的操作,做这件事情性能很低,很有可能会造成全表遍历。
因此通过正排索引来解决聚合问题。

批量查询
1 | 语法: |
1 | //批量查询 查询id =2 和id = 3 的数据 |
1 | //封装,把索引名(product提取出来) |
1 | //再封装 |
1 | //include包含哪些字段 exclude排除哪些字段 |
1 | Operate: |
1 | //手动指定id和自动生成 |
1 | //强制执行创建 如果数据存在则报错 |
1 | //自动生产id(guid) |
当使用PUT进行数据覆盖的时候,Version版本号会上升,旧的Version数据会被删除,不会马上删除,会有一个懒删除的机制。
批量操作
1 | bulk:批量增删改 no-query |
1 | POST /_bulk |
bulk批处理操作要求数据分两行编写,不可以将{}进行换行操作。
1 | //加?filter_path=items.*.error 只显示失败的,返回从操作失败的数据信息 |
1 | //version=2&&version_type=external 通过版本更新数据,避免并发覆盖---CAS |
ES是通过CAS+Version解决并发的问题!!!
最后更新: 2020年12月13日 20:39
原始链接: https://midkuro.gitee.io/2020/12/09/elasticearch-index/