ES_数据存储知识

一、 _source 字段:数据的“真相之源”

1. 是什么?
_source 是一个独立的、特殊的元字段。它存储了你在索引文档时提交的原始JSONbody的完整内容

2. 工作原理与用途

  • 写入:当你索引一个文档 {"title": "My Book", "price": 29.99},这个完整的JSON对象就会被原封不动地存储到 _source 字段中。
  • 读取
    • 搜索返回:当你执行搜索请求,默认返回的 hits.hits._source 里的数据,就是直接从 _source 字段提取的,并非从倒排索引中重建。这是为什么ES搜索返回结果如此之快的原因之一。
    • 重建索引/更新update API和reindex API都严重依赖 _source 字段。更新操作本质上是“获取文档 -> 修改 _source -> 重新索引”;重建索引则是直接从源索引读取 _source 来写入新索引。
    • 高亮(Highlighting):高亮功能通常需要访问原始文本内容来确定字符位置,_source 是其数据来源之一。

3. 禁用 _source
你可以通过映射禁用 _source,但强烈不建议这样做

PUT my_index
{"mappings": {"_source": {"enabled": false},"properties": {...}}
}

禁用后果

  • 无法使用 update API。
  • 无法直接通过 _reindex API 迁移数据。
  • 无法使用高亮(除非显式地将高亮所需字段设置为 "store": true)。
  • 无法在查询结果中看到原始文档。
  • 调试困难。

最佳实践永远不要禁用 _source。如果担心磁盘占用,可以通过索引压缩、使用更高效的硬件等方式解决,而不是牺牲核心功能。


二、 doc_values:列式存储的基石

1. 是什么?
doc_values 是默认开启的、在磁盘上的、基于列式存储的数据结构。它的存在是为了高效地完成排序(Sorting)、聚合(Aggregation)和脚本访问(Scripting)

2. 为什么需要它?
倒排索引是为“查找包含某个词项的文档”而优化的(即搜索)。但要回答“对某个字段进行聚合或排序”就非常困难且低效,因为这需要遍历所有文档并获取字段值。

doc_values 解决了这个问题。它为所有支持它的字段类型(如 keyword, numeric, date, geo_point, ip 等,但不包括 text)在索引时额外创建了一个列式存储结构。

Documentprice (Field Value)
Doc_1100
Doc_2200
Doc_3150

3. 工作原理与用途

  • 列式存储:数据按列(字段)存储,而不是按行(文档)。这使得ES可以高效地:
    • 排序:快速遍历一列中的所有值。
    • 聚合:计算一列中值的总和、平均值、百分位数等。
    • 脚本访问:在脚本中引用 doc['price'].value 时,数据来源于 doc_values
  • 磁盘存储doc_values 存储在磁盘上,但OS会将其缓存到文件系统缓存中,以提供高速访问。

4. 禁用 doc_values
你可以按字段禁用 doc_values,但仅在你100%确定该字段永远不会用于排序、聚合或脚本时才可以这样做。这可以节省磁盘空间。

"my_field": {"type": "keyword","doc_values": false // 谨慎禁用!
}

三、 fielddata:内存中的倒排索引

1. 是什么?
fielddatadoc_values内存版互补方案,主要用于 text 字段。

2. 为什么需要它?
text 字段默认会被分词(analyzed),因此它们默认没有 doc_values。如果你突然需要对一个 text 字段进行聚合或排序(例如,对 product_name 这个 text 字段做 terms 聚合),ES需要能够通过文档ID快速找到该文档的字段值。

fielddata 就是将所有分词后的词项包含它们的文档的对应关系,从磁盘上的倒排索引加载到JVM堆内存中形成的数据结构。这是一个昂贵且延迟高的操作。

3. 工作原理与用途

  • 默认关闭,需要手动在映射中为 text 字段开启。
  • 数据存储在 JVM堆内存中,极易导致内存溢出(OOM)和集群不稳定。
  • 主要用于 text 字段的聚合和排序。
PUT my_index/_mapping
{"properties": {"my_text_field": {"type": "text","fielddata": true // 警告:请谨慎开启!}}
}

4. fielddata vs doc_values

特性doc_valuesfielddata
存储介质磁盘(利用文件系统缓存)JVM堆内存
创建时机索引时首次聚合/排序时(延迟加载)
默认状态对支持字段默认开启text 字段默认关闭
性能影响低,磁盘操作高,极易引起GC压力和OOM
适用字段keyword, numeric, date, iptext

最佳实践极力避免开启 fielddata。如果需要对字符串进行聚合和排序,优先使用 keyword 类型或多字段:

"product_name": {"type": "text",       // 用于全文搜索"fields": {"raw": {            // 用于聚合和排序"type": "keyword" // 使用keyword类型,它天然有doc_values支持}}
}

查询时使用 product_name.raw 进行聚合。


四、 store 参数:存储“额外”的副本

1. 是什么?
默认情况下,字段值存储在 _source 中。如果你设置 "store": true,ES会额外将该字段的值单独存储在一份空间中。

2. 为什么需要它?
主要目的是在查询结果中返回某些特定的、未被 _source 包含的字段,或者_source 中提取某个字段开销很大时(因为 _source 需要被压缩和解压)。

常见误区"store": true 并不会让字段变得可搜索!字段是否可搜索只由 "index" 参数控制。它只影响该字段的值是否可以被单独返回。

3. 使用场景
场景一:_source 被禁用,但你仍希望返回某个字段的值。
场景二:_source 非常大(例如包含一个很长的文本内容),但你只需要频繁返回其中的一两个小字段(如 title, date)。单独存储这些小字段可以避免在每次查询时解压整个庞大的 _source,提升性能。

PUT my_index
{"mappings": {"_source": {"enabled": true // _source 仍然启用},"properties": {"title": {"type": "text","store": true // 额外存储一份},"content": {"type": "text","store": false // 不额外存储,只在 _source 里}}}
}// 查询时,使用 `stored_fields` 来指定返回哪些存储的字段
GET my_index/_search
{"stored_fields": [ "title" ], // 只返回显式声明为store=true的字段"query": {...}
}

最佳实践:这是一个非常高级的优化选项。在绝大多数情况下,你不需要设置 "store": true。依赖 _source 是更简单、更通用的做法。


五、 null_value:处理空值的利器

1. 是什么?
null_value 参数允许你用一个指定的值(如 "NULL", 0, -1)来替换显式的 null,以便该字段可以被搜索和聚合。

2. 为什么需要它?
在ES中,一个字段的值为 null、空数组 [] 或者根本不存在,在Lucene底层是等价的——它们都没有被索引。这意味着你无法通过 term 查询找到值为 null 的文档。

3. 使用方法

"status_code": {"type": "keyword","null_value": "NULL" // 将显式的null替换为字符串"NULL"
}

索引数据

{ "status_code": "active" }
{ "status_code": null }     // 实际在索引中,这个字段的值是 "NULL"
{ }                         // 这个文档的status_code字段不存在,值仍是null

查询
现在,你可以找到所有 status_codenull 的文档了:

GET my_index/_search
{"query": {"term": {"status_code": "NULL" // 搜索被替换后的值}}
}

最佳实践:对于需要区分“空值”业务的字段(如状态码、标签、分类),使用 null_value 可以保证数据的可查询性。


总结与核心建议

概念核心用途默认值建议
_source存储原始文档,用于结果返回、更新、重建索引true永远不要禁用
doc_values为排序、聚合、脚本提供磁盘上的列式存储true (对支持字段)不要禁用,除非绝对确定用不到
fielddatatext 字段的排序聚合提供内存中的数据false极力避免开启,用keyword多字段替代
store额外存储字段值,用于特定优化场景false大多数情况不需要,优先使用_source
null_valuenull替换为可索引/聚合的默认值null按需使用,用于需要查询空值的业务字段

作为一名架构师,你的目标是:

  1. 保证功能:确保 _source 可用。
  2. 追求性能:善用 doc_values,避免使用 fielddata
  3. 精细优化:在明确收益后,再考虑使用 storenull_value 这类高级参数。

透彻理解这些底层机制,将使你能够设计出既高效又稳健的Elasticsearch系统,从容应对各种复杂的业务场景。

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

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

相关文章

day37-Nginx优化

1.每日复盘与今日内容1.1复盘nginx四层转发rewrite tag:last和breakredirect、permanent🍟🍟🍟🍟🍟Nginx内置参数动静分离🍟🍟🍟🍟🍟1.2今日内容N…

Zynq开发实践(fpga高频使用的两个场景)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】本身fpga是介于纯软件和asic之间的元器件。如果是纯软件,那我们要做的,就是纯上层开发。只要相关驱动已经实现,那…

20250822在Ubuntu24.04.2下指定以太网卡的IP地址

20250822在Ubuntu24.04.2下指定以太网卡的IP地址 2025/8/22 20:28缘起:公司的服务器的IP地址老变!,路由器经常被其他其它部门断电重启。 导致IP地址被DHCP服务器给更改了! 直接固定IP地址了。 本来想通过VI命令编辑配置文件来指定…

【yocto】BitBake指令汇总解析

【点关注,不迷路 】BitBake 是一个功能强大且核心的元任务执行器,它是 OpenEmbedded 和 Yocto Project 的构建基石。简单来说,它就像一个高度专业化的 make 工具,但它能解析复杂的元数据(配方、配置、类)&…

CSS @media 媒体查询

media 媒体查询是响应式设计的核心工具,允许根据设备特性(如屏幕宽度、高度、方向等)应用不同的 CSS 样式。一、基本语法media media-type and (media-feature) {/* 目标样式规则 */ }媒体类型(可选):all&a…

Vue2.x核心技术与实战(三)

目录 四、Vue2.x:组件通信&进阶用法 4.1 组件的三大组成部分(结构/样式/逻辑) 4.1.0 组件的三大组成部分-注意点说明 4.1.1 组件的样式冲突 scoped 4.1.2 data是一个函数 4.2 组件通信 4.2.1 什么是组件通信 4.2.2 不同的组件关系和组件通信方案分类 4.2.2 父传子…

泵站远程监控与自动化控制系统:智慧泵房设备的创新实践

在智慧水务快速发展的背景下,泵站自动化控制系统与水泵远程监控技术已成为提升供水效率、保障水质安全、降低运维成本的核心手段。通过物联网、云计算、边缘计算等技术的深度融合,智慧泵房设备实现了从“人工值守”到“无人化智能管理”的跨越式升级&…

校园作品互评管理移动端的设计与实现

摘 要 本文概述了一款运用 Spring Boot 框架精心打造的校园作品互评管理移动端的设 计与实现,其设计初衷在于激发校园内的创作活力,并优化学生间的互评流程,进一 步推动教育模式的创新。该系统深度融合了移动互联网技术,借助小程序…

为什么需要关注Flink并行度?

当你的Flink作业运行时,是否遇到过资源利用率不足或任务堆积的情况?这很可能与并行度设置不当有关。作为流处理领域的"性能放大器",合理配置并行度能带来:提升吞吐量资源成本降低的黄金比例背压问题的天然解决方案一、四…

电脑芯片大的32位与64位指的是什么

32 位与 64 位既不单纯指数据线根数,也不单纯指地址线根数,而是对CPU 核心架构位数的统称,其核心关联以下两个关键硬件指标,需结合场景区分:核心关联:CPU 通用寄存器位数这是 “32 位 / 64 位” 的核心定义…

第1.1节:图灵测试与AI的诞生

🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年6月CSDN上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师…

分布式搜索(Elasticsearch)基本用法

目录 初识Elasticsearch 什么是elasticsearch 正向索引和倒排索引 与mysql进行对比 安装elasticsearch、kibana 安装分词器IK IK分词器的拓展和停用词典 ik分词器-拓展词库 ik分词器-停用词库 索引库操作 mapping映射属性 索引库的CRUD 查看、删除索引库 文档操作 …

docker 查看容器 docker 筛选容器

目录 docker ps 看运行中的容器 运行中的容器筛选容器名 2️⃣ 包括已停止的容器中筛选 3️⃣ 只输出容器 ID(脚本里常用) docker ps 看运行中的容器 docker ps -a 看所有容器 --filter "namexxx" 可以按名字查 运行中的容器筛选容器名 …

策略模式 vs 适配器模式

一、模式本质1 策略模式:行为的选择核心思想:定义一组算法,将每个算法封装起来,并使它们可以互相替换,让算法的变化独立于使用它的客户端。2 适配器模式:接口的转换核心思想:将一个类的接口转换…

Unity--判断一个点是否在扇形区域里面(点乘和叉乘的应用)

问题分享:https://www.bilibili.com/video/BV1zLetz1Ew8 using System.Collections; using System.Collections.Generic; using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endifpublic class SectorCheck : MonoBehaviour {[Tooltip("扇形圆心"…

基于Python sdk发布自己的第一个mcp-client

说在前面 上一篇文章发布了一个mcp-server,具体的server是否能被正确的访问到?是否能够得到正常的返回? 在github上找到一个客户端的代码实现,我把里面的大模型调用换成了支持国内大模型的方式,一起来验证一下吧~ 主…

C# 浮点数与定点数详细解析

C# 浮点数与定点数详细解析 在 C# 中,数值类型主要分为: 整数型(int, long 等)浮点型(float, double)定点型(decimal) 浮点数和定点数在内部的表示方式不同,导致它们的 精…

【小宁学习日记5 stm32】LED闪烁 LED流水灯 蜂鸣器

目录 01.LED闪烁 1、搭建电路板 2、新建工程 (1)前期准备 (2)创建工程文件夹结构 (3)复制固件库文件到对应文件夹 (4)在 Keil 中创建工程 (5)配置工程…

openstack的novnc兼容问题

1.今天在部署O版过程中发现了novnc组件不兼容openstack2.novnc一直报错,令牌过期,原本以为是python代码配置的问题,最后经过排查很久发现竟然是novnc的版本和openstack的O版不兼容novncyum remove -y novnc*安装支持版本yum install -y novnc…

Day25 栈 队列 二叉树

day25 栈 队列 二叉树使用栈计算表达式的值 概述 通过两个栈(数值栈和符号栈)实现中缀表达式求值。算法核心是: 遇到数字时,累加并入数值栈;遇到运算符时,比较其与符号栈顶运算符的优先级: 若当…