ToB企服应用市场:ToB评测及商务社交产业平台

标题: 深入剖析Elasticsearch的内部数据结构和机制:行存储、列存储与倒排索引之 [打印本页]

作者: 王柳    时间: 2024-8-27 23:52
标题: 深入剖析Elasticsearch的内部数据结构和机制:行存储、列存储与倒排索引之
❃博主首页 :   「码到三十五」   ,同名公众号 :「码到三十五」,wx号 : 「liwu0213」   
  ☠博主专栏 :   <mysql高手>    <elasticsearch高手>    <源码解读>    <java核心>    <面试攻关>   
  ♝博主的话 :  搬的每块砖,皆为峰峦之基;公众号搜索「码到三十五」关注这个爱发技术干货的coder,一起筑基   
   在当今的大数据时代,高效的数据检索和分析本领已成为许多应用程序的核心需求。Elasticsearch,作为一款强大的分布式搜索和分析引擎,正是为了满足这些需求而诞生的。它之所以能够在海量数据中实现毫秒级的搜索相应,以及机动的数据分析,要归功于其内部精妙的数据结构和机制。本文将详细探究Elasticsearch中的行存储(Stored Fields)、列存储(Doc Values)和倒排索引(Inverted Index)这三种关键组件,并解释它们是如何协同工作的。
  
  
1、 什么是行存

在Lucene中索引文档时,原始字段信息经过分词、转换处置惩罚后形成倒排索引,而原始内容本身并不直接保留。因此,为了检索时能够获取到字段的原始值,我们需要依赖额外的数据结构。Lucene提供了两种解决方案:Stored Field和doc_values。
Stored Field的设计初衷就是为了存储那些未经分词的字段原始值。这样,在执行查询操作时,除了能够获取到文档ID之外,我们还能够方便地检索到这些原始字段信息。
es中每个文档都被视为一个JSON对象,包罗多个字段。当文档被索引时,其原始数据或特定字段可以被存储在es中,以便后续能够检索到原始的字段值。这种存储方式类似于传统的行存储数据库,由于它存储了每个文档的所有字段。
然而,需要注意的是,es并不建议大量使用Stored Fields。这是由于存储原始字段值会增加磁盘使用量,并可能降低性能。相反,es更倾向于使用Doc Values和倒排索引来高效地检索和分析数据。因此,Stored Fields通常只用于存储那些需要在搜索结果中直接返回的字段。
2、 使用场景

那么,什么时候应该使用Stored Fields呢?

3、 如何使用

可以通过映射(Mapping)来定义哪些字段应该被存储为Stored Fields。映射是定义文档结构和字段属性的过程。
3.1 定义store字段

  1. PUT order
  2. {
  3.    "mappings": {
  4.       "_doc": {
  5.          "properties": {
  6.             "counter": {
  7.                "type": "integer",
  8.                "store": false        //默认值就是false
  9.             },
  10.             "tags": {
  11.                "type": "keyword",
  12.                "store": true      //修改值为true
  13.             }
  14.          }
  15.       }
  16.    }
  17. }
复制代码
我们创建了一个名为order的索引,并定义了两个字段:counter和tags。我们将tags字段的store属性设置为true,这意味着tags字段的值将被存储为Stored Fields。而counter字段的store属性设置为false,表示不存储该字段的值。
3.2 添加 document

  1. PUT order/_doc/1
  2. {
  3.     "counter" : 1,
  4.     "tags" : ["red"]
  5. }
复制代码
3.3 实验带stored_fields参数去检索

  1. GET twitter/_doc/1?stored_fields=tags,counter
  2. 以上get操作的结果是:
  3. {
  4.    "_index": "twitter",
  5.    "_type": "tweet",
  6.    "_id": "1",
  7.    "_version": 1,
  8.    "found": true,
  9.    "fields": {           //此时多了名称为fields的字段,并且没有了_source
  10.       "tags": [          //tags的stroe属性设置为true,因此显示在结果中
  11.          "red"
  12.       ]
  13.    }
  14. }
复制代码
从 document 中获取的字段的值通常是array。
由于counter字段没有存储,当实验获取stored_fields时get会将其忽略。
在Elasticsearch中,不论将字段的store属性设置为true还是false,这些字段都会被存储。但存储的方式有所不同:

那么,在什么情况下需要将字段的store属性设置为true呢?通常有两种情况:

4、 行存储与_source字段

行存储中,占比最大的通常是_source字段,它负责保存文档的原始数据。在数据写入阶段,Elasticsearch会将整个文档的JSON结构体作为字符串存储在_source字段中。在查询时,我们可以通过_source字段检索到原始写入的完整JSON结构体。

  1. {
  2.     "_index": "order",
  3.     "_type": "_doc",
  4.     "_id": "1",
  5.     "_version": 1,
  6.     "_seq_no": 0,
  7.     "_primary_term": 1,
  8.     "found": true,
  9.     "_source": {      //默认查询数据,返回的属性字段都在_source中
  10.         "user": "kimchy",
  11.         "post_date": "2009-11-15T14:12:12",
  12.         "message": "trying out Elasticsearch"
  13.     }
  14. }
复制代码
4.1 _source字段


4.2 优化_source字段的使用


4.3 注意事项


5、 总结

行存储有几个重要的长处:

然而,行存储也有一些潜在的开销和限制:

   在使用ES时,开发者需要根据详细的应用场景和需求来权衡行存储的利弊,并合理地配置和优化索引结构。例如,在某些场景下,可能只需要存储文档的部分字段而不是完整的JSON结构体,这可以通过在映射中关闭_source字段或只包罗须要的字段来实现。然而,需要注意的是,关闭_source字段后将无法使用依赖于_source字段的ES功能,如更新、重新索引等。因此,在做出决定时需要仔细考虑。
  
    关注公众号[码到三十五]获取更多技术干货 !   


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4