如何理解Elasticsearch的内部数据结构

发布时间:2021-10-26 17:05:09 作者:iii
来源:亿速云 阅读:264

这篇文章主要介绍“如何理解Elasticsearch的内部数据结构”,在日常操作中,相信很多人在如何理解Elasticsearch的内部数据结构问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何理解Elasticsearch的内部数据结构”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

1、数据存储认知前提

正如 Elastic 官方文档所说:

Elasticsearch 特点之一是:分布式文档存储。

Elasticsearch不会将信息存储为类似列数据库的行(row),而是存储为已序列化为JSON文档的复杂数据结构。

当集群中有多个Elasticsearch节点时,存储的文档会分布在整个集群中,并且可以从任何节点立即访问。

存储文档后,将在1秒钟内(默认刷新频率为1s)几乎实时地对其进行索引和完全搜索。

如何做到快速索引和全文检索的呢? 

Elasticsearch使用倒排索引的数据结构,该结构支持非常快速的全文本搜索。

倒排索引列出了出现在任何文档中的每个唯一单词,并标识了每个单词出现的所有文档。

索引可以认为是文档的优化集合,每个文档都是字段的集合,这些字段是包含数据的键值对。

如何理解Elasticsearch的内部数据结构

默认情况下,Elasticsearch 对每个字段中的所有数据建立索引,并且每个索引字段都具有专用的优化数据结构。

例如,文本字段存储在倒排索引中,数字字段和地理字段存储在BKD树中。

数据类型数据结构
text/keyword倒排索引
数字/地理位置BKD树

不同字段具有属于自己字段类型的特定优化数据结构,并具备快速响应返回搜索结果的能力使得 Elasticsearch 搜索飞快! 

1、Inverted Index 倒排索引

1.1 倒排索引定义

面对海量内容,如何快速的找到包含用户查询词的内容,倒排索引扮演了关键角色。

倒排索引是单词到文档映射关系的最佳实现形式。

下图是:书的末页的索引结构,展示了核心关键词与书页码的对应关系。

如何理解Elasticsearch的内部数据结构

试想一下,没有这个索引页,根据关键词从全书查找有多慢,就能直观体会出索引的妙处!

1.2 倒排索引示例

拿官方文档的示例:

假设我们有两个文档,每个文档的 content 域包含如下内容:

- 1、The quick brown fox jumped over the lazy dog
- 2、Quick brown foxes leap over lazy dogs in summer
 

对索引编制索引会受到标记化和标准化的处理analysis。

数据索引化制约因素:分词器 analyzer 的选型。

倒排索引(基于 默认Standard 标准分词器分词)如下所示:

TermDoc_1Doc_2
Quick
X
TheX
brownXX
dogX
dogs
X
foxX
foxes
X
in
X
jumpedX
lazyXX
leap
X
overXX
quickX
summer
X
theX

如上所示,对于文档中的每个词,都包含了其所在文档的列表。 

1.3 倒排索引特点

1.4 倒排索引适用场景

2、Doc Values 正排索引 

2.1 Doc Values 定义

在 Elasticsearch 中,Doc Values 就是一种列式存储结构,默认情况下每个字段的 Doc Values 都是激活的(除了 text 类型),Doc Values 是在索引时创建的,当字段索引时,Elasticsearch 为了能够快速检索,会把字段的值加入倒排索引中,同时它也会存储该字段的 Doc Values。

区别于倒排索引的定义,Doc Values 被定义为:“正排索引”。

如何理解Elasticsearch的内部数据结构 

2.2 Doc Values 示例

仍然 以 1.2 文档为例,Doc Values 结构如下所示(仅做举例):

DocTerms
Doc_1brown, dog, fox, jumped, lazy, over, quick, the
Doc_2brown, dogs, foxes, in, lazy, leap, over, quick, summer

Doc values 通过转置两者间的关系来解决适用倒排索引聚合效率低、难以扩展的问题。

对比可以看出:倒排索引将词项映射到包含它们的文档,doc values 将文档映射到它们包含的词项。

 

2.3 Doc Values 特点

2.4 Doc Values 适用场景

Elasticsearch 中的 Doc Values 常被应用到以下场景:

注意:

因为文档值被序列化到磁盘,我们可以依靠操作系统的帮助来快速访问。

2. 5 Doc Values 使用注意事项

对于不需要:排序、聚合、脚本计算、地理位置过滤的业务场景,可以考虑禁用:Doc Values,以节约存储。

PUT my_index
{
  "mappings": {
      "properties": {
        "title": {
          "type": "keyword",
          "doc_values": false 
        }
    }
  }
}
   

3、fielddata 

3.1 fielddata 定义

如前第1、2小结所述:

text 类型字段是不支持 Doc Values正排索引的,text字段使用是:查询时创建的基于的内存数据结构(query-time in-memory data structure) fielddata。

fielddata 将 text 字段用于聚合、排序或在脚本中使用时,将按需构建此数据结构。

实现机理:它是通过从磁盘读取每个段的整个反向索引,反转词项↔︎文档关系并将结果存储在JVM堆中的内存中来构建的。 

3.2 fielddata 示例

严格意义讲,2.2 的示例,放到这里会更合适。

DELETE test_001
PUT test_001
{
  "mappings": {
    "properties": {
      "body":{
        "type":"text",
        "analyzer": "standard",
        "fielddata": true
      }
    }
  }
}

POST test_001/_bulk
{"index":{"_id":1}}
{"body":"The quick brown fox jumped over the lazy dog"}
{"index":{"_id":2}}
{"body":"Quick brown foxes leap over lazy dogs in summer"}

GET test_001/_search
{
  "size": 0,
  "query": {
    "match": {
      "body": "brown"
    }
  },
  "aggs": {
    "popular_terms": {
      "terms": {
        "field": "body"
      }
    }
  }
}
   

3.3 fielddata 特点

3.4 fielddata 适用场景

 

3.5 fielddata 使用注意事项

4、_source 字段解读 

4.1 _source 定义

_source 字段包含在索引时间传递的原始JSON文档主体。

_source 字段本身未构建索引(因此不可搜索),但已存储该字段,以便在执行获取请求(如get或search)时可以将其返回。

 

4.2 _source 使用注意事项

第一:尽管非常方便,但是source字段确实会导致索引内的存储开销。因此,可以将其禁用。

PUT my-index-000001
{
  "mappings": {
    "_source": {
      "enabled": false
    }
  }
}
 

第二:禁用前要做好以下衡量 禁用 _source 后,如下操作将不可用:

  1. update, update_by_query 和 reindex API

  2. 高亮操作

所以,要在存储空间、业务场景之间权衡利弊后选型。

5、store 字段解读 

5.1 store 定义

默认情况下,对字段值进行索引以使其可搜索(第1节的 倒排索引),但不存储它们。

这意味着可以查询该字段,但是无法检索原始字段值。

通常这无关紧要。该字段值已经是_source字段的一部分,默认情况下已存储。

但,某些特殊场景下,如果你只想检索单个字段或几个字段的值,而不是整个_source的值,则可以使用源过滤来实现。

这个时候, store 就派上用场了。 

5.2 store 示例

DELETE news-000001
PUT news-000001
{
  "mappings": {
    "_source": {
      "enabled": false
    },
    "properties": {
      "title": {
        "type": "text",
        "store": true
      },
      "date": {
        "type": "date",
        "store": true
      },
      "content": {
        "type": "text"
      }
    }
  }
}

PUT news-000001/_doc/1
{
  "title":   "Some short title",
  "date":    "2021-01-01",
  "content": "A very long content field..."
}

GET news-000001/_search

GET news-000001/_search
{
  "stored_fields": [ "title", "date" ] 
}
   

5.3 store 适用场景

如 5.2 示例,在某些情况下,存储字段可能很有意义。例如,采集的新闻数据是:带有标题、日期和很大内容字段的文档,

则可能只想检索标题和日期,而不必从较大的_source字段中提取这些字段。 

到此,关于“如何理解Elasticsearch的内部数据结构”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

推荐阅读:
  1. Redis中内部数据结构intset的作用是什么
  2. 如何理解redo的内部过程与lgwr

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java elasticsearch

上一篇:如何掌握Java变量

下一篇:Python语法检查引用PyLint配置的具体方法是什么

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》