深入解析Elasticsearch的内部数据结构和机制:行存储、列存储与倒排索引之行存(一)

在当今的大数据时代,高效的数据检索和分析能力已成为许多应用程序的核心需求。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呢?

  • 需要返回原始字段值:如果你的应用程序需要在搜索结果中返回文档的原始字段值,那么你应该将这些字段设置为Stored Fields。例如,你可能需要显示给用户文档的标题、描述或内容等字段。
  • 不支持Doc Values的字段类型:并非所有字段类型都支持Doc Values。对于那些不支持Doc Values的字段类型,如果你需要在搜索结果中返回这些字段的值,那么你需要将它们设置为Stored Fields。

3 如何使用

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

3.1 定义store字段
PUT order
{"mappings": {"_doc": {"properties": {"counter": {"type": "integer","store": false        //默认值就是false},"tags": {"type": "keyword","store": true      //修改值为true}}}}
}

我们创建了一个名为order的索引,并定义了两个字段:counter和tags。我们将tags字段的store属性设置为true,这意味着tags字段的值将被存储为Stored Fields。而counter字段的store属性设置为false,表示不存储该字段的值。

3.2 添加 document
PUT order/_doc/1
{"counter" : 1,"tags" : ["red"]
}
3.3 尝试带stored_fields参数去检索
GET twitter/_doc/1?stored_fields=tags,counter以上get操作的结果是:{"_index": "twitter","_type": "tweet","_id": "1","_version": 1,"found": true,"fields": {           //此时多了名称为fields的字段,并且没有了_source"tags": [          //tags的stroe属性设置为true,因此显示在结果中"red"]}
}

从 document 中获取的字段的值通常是array。
由于counter字段没有存储,当尝试获取stored_fields时get会将其忽略。

在Elasticsearch中,不论将字段的store属性设置为true还是false,这些字段都会被存储。但存储的方式有所不同:

  • 当store设置为false时(这是默认配置),字段值仅存储在文档的_source字段中。这意味着,字段值作为整个文档JSON结构体的一部分被保存。
  • 当store设置为true时,字段值不仅存储在_source字段中,还会被单独存储在一个与_source平级的独立字段中。这样,该字段就有了两份拷贝:一份在_source中,另一份在独立的字段中。

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

  • _source字段在索引的映射中被禁用(disabled)
    在这种情况下,如果某个字段没有被定义为store=true,那么该字段将不会出现在查询结果中。因此,为了确保能够在查询结果中访问这些字段,需要将其设置为store=true。
  • _source字段的内容非常大
    当文档包含大量数据时,例如一本书的内容,而查询时只需要访问其中的部分字段(如标题和日期),而不是整个_source字段,那么将这些字段设置为store=true可以提高查询效率。这样做可以避免在查询时解释整个_source字段,从而减少开销。当然,另一种选择是使用source filtering来减少网络开销,但将特定字段设置为store=true也是一种有效的优化方法。

4 行存储与_source字段

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

在这里插入图片描述

{"_index": "order","_type": "_doc","_id": "1","_version": 1,"_seq_no": 0,"_primary_term": 1,"found": true,"_source": {      //默认查询数据,返回的属性字段都在_source中"user": "kimchy","post_date": "2009-11-15T14:12:12","message": "trying out Elasticsearch"}
}

_source字段:

  • _source字段的角色:在Elasticsearch中,每个索引的文档都有一个特殊的字段叫做_source。这个字段包含了文档的原始JSON表示。当你索引一个文档时,Elasticsearch会将这个文档的JSON形式存储为_source字段的内容。这意味着,无论你的文档包含什么字段(例如,标题、描述、日期等),它们都会被打包进这个_source字段中。
  • 存储与检索:由于_source字段存储了文档的完整原始数据,因此它通常是索引中最大的字段之一。当你执行一个检索操作时,Elasticsearch默认会返回匹配文档的_source字段,从而允许你访问到文档的原始数据。
  • 用途:拥有文档的原始数据非常有用,特别是在你需要重新构建文档的上下文时(例如,在搜索结果中显示文档的内容)。此外,许多Elasticsearch的功能,如高亮显示或字段提取,都依赖于_source字段的内容。

优化_source字段的使用:

  • 关闭_source:如果你确定不需要文档的原始数据,可以在索引的映射中关闭_source字段的存储。这样做可以节省存储空间并提高索引速度。然而,这样做有一个重要的限制:关闭_source字段后,你将无法使用update、update_by_query和reindex等API,因为这些操作需要访问文档的原始数据。
  • 包含/排除字段:另一种优化方法是选择性地包含或排除_source字段中的某些数据。例如,你可能只想存储文档的某些关键字段,而不是整个JSON结构体。这可以通过在索引文档时使用特定的参数或在映射中定义_source字段的包含/排除规则来实现。

注意事项:

  • 在决定关闭_source字段或修改其包含的内容之前,务必仔细考虑你的应用程序的需求。如果你在未来需要使用文档的原始数据,或者需要使用依赖于_source字段的Elasticsearch功能,那么关闭或修改_source字段可能会导致问题。
  • 尽管关闭_source字段可以节省存储空间,但这通常不是优化Elasticsearch性能的首选方法。在大多数情况下,通过优化查询、选择合适的分析器、合理设置映射和使用硬件资源等方式,可以获得更好的性能提升。

5 总结

行存储有几个重要的优点:

  • 完整性:由于_source字段存储了文档的完整原始数据,因此可以重新构建文档的上下文,这对于搜索结果展示、高亮显示等功能至关重要。
  • 灵活性:拥有文档的原始数据使得ES能够提供多种功能,如字段提取、动态映射更改等,这些功能都依赖于_source字段的内容。
  • 便于调试:对于开发者而言,能够直接访问文档的原始数据有助于调试和验证索引的正确性。

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

  • 存储成本:由于每个文档的完整原始数据都被存储在索引中,这可能会增加存储空间的需求,尤其是对于大量文档或大型文档而言。
  • 写入性能:在写入大量文档时,将每个文档的完整JSON结构体存储到_source字段可能会对写入性能产生一定的影响。

在使用ES时,开发者需要根据具体的应用场景和需求来权衡行存储的利弊,并合理地配置和优化索引结构。例如,在某些场景下,可能只需要存储文档的部分字段而不是完整的JSON结构体,这可以通过在映射中关闭_source字段或只包含必要的字段来实现。然而,需要注意的是,关闭_source字段后将无法使用依赖于_source字段的ES功能,如更新、重新索引等。因此,在做出决策时需要仔细考虑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/668425.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

笔记本电脑的WIFI模块,突然不显示了,网络也连接不上

问题复现: 早上,在更新完笔记本电脑的系统之后,连网之后,网络突然直接断开,一查看,WiFi模块居然不见了,开机重启也是如此,这种情况常常出现在更新系统之后,WiFi模块驱动就…

RK3399平台开发系列讲解(内存篇)进程内存详解

🚀返回专栏总目录 文章目录 一、虚拟地址映射的物理内存1.1、物理内存1.2、虚拟内存1.2.1、用户态:低特权运行程序1.2.2、内核态:运行的程序需要访问操作系统内核数据二、PageCache三、指标查询命令沉淀、分享、成长,让自己和他人都能有所收获!😄 📢进程消耗的内存包…

docker proxy 【docker 代理】

第一种 创建代理配置文件 mkdir -p /etc/systemd/system/docker.service.d/ cat <<EOF > /etc/systemd/system/docker.service.d/http-proxy.conf Environment"HTTP_PROXYhttp://192.168.21.101:7890" Environment"HTTPS_PROXYhttp://192.168.21.1…

同城外卖跑腿app开发:重新定义城市生活

随着科技的发展和人们生活节奏的加快&#xff0c;同城外卖跑腿app应运而生&#xff0c;成为现代城市生活中的重要组成部分。本文将探讨同城外卖跑腿app开发的意义、市场需求、功能特点以及未来的发展趋势。 一、同城外卖跑腿app开发的意义 同城外卖跑腿app作为一种便捷的生活…

sqli.labs靶场(41-53关)

41、第四十一关 -1 union select 1,2,3-- -1 union select 1,database(),(select group_concat(table_name) from information_schema.tables where table_schemadatabase()) -- -1 union select 1,2,(select group_concat(column_name) from information_schema.columns wher…

0基础学习VR全景平台篇第141篇:如何制作卫星航拍全景

大家好&#xff0c;欢迎观看蛙色官方系列全景摄影课程&#xff01; 很多人都看过或者拍摄过航拍全景&#xff0c;其效果相比于普通的地拍的确有着更加震撼的拍摄效果&#xff0c;但是受限于无人机高度&#xff0c;以及禁飞区等等限制&#xff0c;导致很多大场景无法展示完全&a…

Linux防火墙与iptables五表五链规则介绍

目录 一、防火墙基本认识 1. 安全技术 2. 防火墙分类 3. 防火墙工具介绍 二、iptables 1. 概述 2. 五表五链 3. 语法 3.1 基本语法 3.2 语法总结 4. 管理选项 5. 通用匹配 6. 控制类型 7. iptables应用 7.1 新增防火墙规则 7.2 查看规则表 7.3 黑白名单 7.4 …

C++ 调用lua 脚本

需求&#xff1a; 使用Qt/C 调用 lua 脚本 扩展原有功能。 步骤&#xff1a; 1&#xff0c;工程中引入 头文件&#xff0c;库文件。lua二进制下载地址&#xff08;Lua Binaries&#xff09; 2&#xff0c; 调用脚本内函数。 这里调用lua 脚本中的process函数&#xff0c;并…

canvas图片上设置镂空文字效果

查看专栏目录 canvas实例应用100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…

C语言-3

定义指针 /*指针的概念:1.为了方便访问内存中的内容&#xff0c;给每一个内存单元&#xff0c;进行编号&#xff0c;那么我们称这个编号为地址&#xff0c;也就是指针。2.指针也是一种数据类型&#xff0c;指针变量有自己的内存&#xff0c;里面存储的是地址&#xff0c;也就是…

【HarmonyOS应用开发】APP应用的通知(十五)

相关介绍 通知旨在让用户以合适的方式及时获得有用的新消息&#xff0c;帮助用户高效地处理任务。应用可以通过通知接口发送通知消息&#xff0c;用户可以通过通知栏查看通知内容&#xff0c;也可以点击通知来打开应用&#xff0c;通知主要有以下使用场景&#xff1a; 显示接收…

BUGKU-WEB Simple_SSTI_1

02 Simple_SSTI_1 题目描述 没啥好说的~ 解题思路 进入场景后&#xff0c;显示&#xff1a; You need pass in a parameter named flag。ctrlu 查看源码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><titl…

代码随想录 Leetcode491. 非递减子序列

题目&#xff1a; 代码(首刷看解析 2024年2月3日&#xff09;&#xff1a; class Solution { private:vector<vector<int>> res;vector<int> path; public:void backtracking(vector<int>& nums, int startIndex) {if (path.size() > 1) {res.…

HSM加密机原理:密钥管理和加密操作从软件层面转移到物理设备中 DUKPT 安全行业基础8

HSM加密机原理 硬件安全模块&#xff08;HSM&#xff09;是一种物理设备&#xff0c;设计用于安全地管理、处理和存储加密密钥和数字证书。HSM广泛应用于需要高安全性的场景&#xff0c;如金融服务、数据保护、企业安全以及政府和军事领域。HSM提供了一种比软件存储密钥更安全…

Web html和css

目录 1 前言2 HTML2.1 元素(Element)2.1.1 块级元素和内联(行级)元素2.1.2 空元素 2.2 html页面的文档结构2.3 常见标签使用2.3.1 注释2.3.2 标题2.3.3 段落2.3.4 列表2.3.5 超链接2.3.6 图片2.3.7 内联(行级)标签2.3.8 换行 2.4 属性2.4.1 布尔属性 2.5 实体引用2.6 空格2.7 D…

vue3 之 组合式API—生命周期函数

vue3的生命周期API 生命周期函数基本使用 1️⃣导入生命周期函数 2️⃣执行生命周期函数 传入回调 <scirpt setup> import { onMounted } from vue onMounted(()>{// 组件挂载完毕mounted执行了 }) </script>执行多次 生命周期函数是可以执行多次的&#xff…

支持多字体、静动态的.NET图片验证码的开源项目

上次分享过 SkiaSharp 这个开源图形项目&#xff0c;并举了一个生成验证码的例子&#xff0c;具体见文章&#xff1a;《SkiaSharp&#xff1a;.NET强大而灵活的跨平台图形库》。 但文中验证码比较简单&#xff0c;刚好看到一个非常不错的图片验证码&#xff0c;分享给大家。 …

ChatGPT之搭建API代理服务

简介 一行Docker命令部署的 OpenAI/GPT API代理&#xff0c;支持SSE流式返回、腾讯云函数 。 项目地址&#xff1a;https://github.com/easychen/openai-api-proxy 这个项目可以自行搭建 OpenAI API 代理服务器工具&#xff0c;该项目是代理的服务器端&#xff0c;不是客户端。…

MySQL 用户管理

重点&#xff1a; 视图&#xff0c;函数&#xff0c;存储过程&#xff0c;触发器&#xff0c;事件&#xff08; 了解 &#xff09; 用户管理&#xff0c;密码管理 grant revoke 权限管理 MySQL 架构&#xff08; 了解 &#xff09; 存储引擎&#xff1a;MyISAM 和 InnoDB …

【JavaScript 漫游】【008】错误处理机制

文章简介 本文为【JavaScript 漫游】专栏的第 008 篇文章&#xff0c;记录了笔者所学习到的错误处理机制的所有知识点。 Error 实例对象原生错误类型&#xff0c;包括 SyntaxError、ReferenceError、RangeError、TypeError、URIError对象自定义错误throw 语句try...catch 结构…