Elasticsearch 映射(mapping)
概念
在 Elasticsearch 中,映射(Mapping)定义了索引中字段的类型和属性。它是索引数据结构的基础,类似于传统数据库中的表结构定义。映射不仅定义了字段的类型(如 text
、keyword
、integer
等),还定义了字段的分析器、是否存储、是否索引等属性。映射是 Elasticsearch 中定义索引字段类型和属性的重要概念。通过显式定义映射,你可以控制字段的类型、分析器和其他属性,从而更好地管理和优化索引数据。动态映射则提供了灵活性,使得在没有显式映射的情况下也能插入数据。
映射的基本概念
-
字段类型:Elasticsearch 支持多种字段类型,包括文本(
text
)、关键字(keyword
)、整数(integer
)、浮点数(float
)、日期(date
)、布尔(boolean
)等。 -
分析器:对于文本字段,可以指定分析器(Analyzer),用于在索引和搜索时对文本进行分词和处理。
-
多字段:一个字段可以有多个子字段(Multi-fields),每个子字段可以有不同的类型和分析器。
-
动态映射:如果没有显式定义映射,Elasticsearch 可以根据插入的数据自动推断字段类型,这称为动态映射(Dynamic Mapping)。
动态映射规则
动态映射(Dynamic Mapping)是 Elasticsearch 中一个非常强大的功能,它允许 Elasticsearch 根据插入的数据自动推断字段类型,从而简化索引的创建和管理。Elasticsearch 使用一组预定义的规则来推断字段类型,这些规则称为动态映射规则。
以下是 Elasticsearch 中一些常见的动态映射规则:
1. 字符串(String):
- 如果字符串包含日期格式,Elasticsearch 会将其推断为 `date` 类型。
- 如果字符串包含数字格式,Elasticsearch 会将其推断为 `float` 或 `long` 类型。
- 否则,Elasticsearch 会将其推断为 `text` 类型,并为其创建一个子字段 `keyword` 类型。
2. 数字(Number):
- 如果字段值是整数,Elasticsearch 会将其推断为 `long` 类型。
- 如果字段值是浮点数,Elasticsearch 会将其推断为 `float` 类型。
3. 布尔(Boolean):
- 如果字段值是 `true` 或 `false`,Elasticsearch 会将其推断为 `boolean` 类型。
4. 对象(Object):
- 如果字段值是一个 JSON 对象,Elasticsearch 会将其推断为 `object` 类型。
5. 数组(Array):
- 如果字段值是一个数组,Elasticsearch 会根据数组中的第一个元素类型来推断字段类型。
6. 日期(Date):
- 如果字段值是一个日期字符串,Elasticsearch 会将其推断为 `date` 类型。
示例
假设你插入以下文档到 Elasticsearch:
PUT /my_index/_doc/1 {"name": "John Doe","age": 30,"is_active": true,"created_at": "2023-10-01T12:00:00Z","tags": ["elasticsearch", "mapping"] } |
Elasticsearch 会根据动态映射规则推断以下字段类型:
- `name`:`text` 类型,并为其创建一个子字段 `keyword` 类型。
- `age`:`long` 类型。
- `is_active`:`boolean` 类型。
- `created_at`:`date` 类型。
- `tags`:`keyword` 类型(因为数组中的元素是字符串)。
控制动态映射
你可以通过设置索引的动态映射策略来控制动态映射的行为。以下是一些常见的动态映射策略:
1. **true**:启用动态映射(默认)。
2. **false**:禁用动态映射,忽略新字段。
3. **strict**:如果遇到新字段,抛出异常。
例如,禁用动态映射:
PUT /my_index {"mappings": {"dynamic": "false"} } |
动态映射规则是 Elasticsearch 自动推断字段类型的一组预定义规则。通过了解这些规则,你可以更好地理解和控制 Elasticsearch 如何处理新字段。动态映射提供了灵活性,使得在没有显式映射的情况下也能插入数据,但有时也需要通过设置动态映射策略来控制其行为。在生产环境中,为了确保数据的结构和类型一致性,以及避免潜在的性能问题和数据不一致,强烈建议显式定义索引的映射。
问题
版本开发中,业务场景需求,增加字段disposalstatus ,升级包中增加了该字段数据模型的SQL语句,由于在升级版本的过程中,升级的时候未先更新数据模型,未先新增字段映射,导致接入数据时,ES采用了动态映射的方式进行了数据的写入,然后再升级数据模型和ES索引mapping更新时,索引中字段已新增,并且字段类型不一致,触发了报错
[2024-08-02T17:37:59,956][DEBUG][o.e.a.a.i.m.p.TransportPutMappingAction] [HOxfa0m] failed to put mappings on indices [[[alert_trace_v0/htU57CoYTQeLgs9Cxo2Mvg]]], type [alert_trace] java.lang.IllegalArgumentException: mapper [disposalstatus] of different type, current_type [text], merged_type [keyword]at org.elasticsearch.index.mapper.FieldMapper.doMerge(FieldMapper.java:354) ~[elasticsearch-6.8.23.jar:6.8.23]at org.elasticsearch.index.mapper.TextFieldMapper.doMerge(TextFieldMapper.java:876) ~[elasticsearch-6.8.23.jar:6.8.23]at org.elasticsearch.index.mapper.FieldMapper.merge(FieldMapper.java:340) ~[elasticsearch-6.8.23.jar:6.8.23]at org.elasticsearch.index.mapper.FieldMapper.merge(FieldMapper.java:52) ~[elasticsearch-6.8.23.jar:6.8.23]at org.elasticsearch.index.mapper.ObjectMapper.doMerge(ObjectMapper.java:487) ~[elasticsearch-6.8.23.jar:6.8.23]at org.elasticsearch.index.mapper.RootObjectMapper.doMerge(RootObjectMapper.java:278) ~[elasticsearch-6.8.23.jar:6.8.23]at org.elasticsearch.index.mapper.ObjectMapper.merge(ObjectMapper.java:457) ~[elasticsearch-6.8.23.jar:6.8.23]at org.elasticsearch.index.mapper.RootObjectMapper.merge(RootObjectMapper.java:273) ~[elasticsearch-6.8.23.jar:6.8.23]at org.elasticsearch.index.mapper.Mapping.merge(Mapping.java:91) ~[elasticsearch-6.8.23.jar:6.8.23]at org.elasticsearch.index.mapper.DocumentMapper.merge(DocumentMapper.java:339) ~[elasticsearch-6.8.23.jar:6.8.23]at org.elasticsearch.cluster.metadata.MetaDataMappingService$PutMappingExecutor.applyRequest(MetaDataMappingService.java:273) ~[elasticsearch-6.8.23.jar:6.8.23]at org.elasticsearch.cluster.metadata.MetaDataMappingService$PutMappingExecutor.execute(MetaDataMappingService.java:231) ~[elasticsearch-6.8.23.jar:6.8.23]at org.elasticsearch.cluster.service.MasterService.executeTasks(MasterService.java:643) ~[elasticsearch-6.8.23.jar:6.8.23]at org.elasticsearch.cluster.service.MasterService.calculateTaskOutputs(MasterService.java:270) ~[elasticsearch-6.8.23.jar:6.8.23]at org.elasticsearch.cluster.service.MasterService.runTasks(MasterService.java:200) [elasticsearch-6.8.23.jar:6.8.23]at org.elasticsearch.cluster.service.MasterService$Batcher.run(MasterService.java:135) [elasticsearch-6.8.23.jar:6.8.23]at org.elasticsearch.cluster.service.TaskBatcher.runIfNotProcessed(TaskBatcher.java:150) [elasticsearch-6.8.23.jar:6.8.23]at org.elasticsearch.cluster.service.TaskBatcher$BatchedTask.run(TaskBatcher.java:188) [elasticsearch-6.8.23.jar:6.8.23]at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingRunnable.run(ThreadContext.java:708) [elasticsearch-6.8.23.jar:6.8.23]at org.elasticsearch.common.util.concurrent.PrioritizedEsThreadPoolExecutor$TieBreakingPrioritizedRunnable.runAndClean(PrioritizedEsThreadPoolExecutor.java:252) [elasticsearch-6.8.23.jar:6.8.23]at org.elasticsearch.common.util.concurrent.PrioritizedEsThreadPoolExecutor$TieBreakingPrioritizedRunnable.run(PrioritizedEsThreadPoolExecutor.java:215) [elasticsearch-6.8.23.jar:6.8.23]at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_332]at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_332]at java.lang.Thread.run(Thread.java:750) [?:1.8.0_332] |
问题一,出现这个错误会影响数据的写入吗
在Elasticsearch中,当你遇到类似 [DEBUG][o.e.a.a.i.m.p.TransportPutMappingAction] ... failed to put mappings ... mapper [disposalstatus] of different type, current_type [text], merged_type [keyword]
的错误时,这意呀着你尝试更改一个已存在字段(在这个例子中是 disposalstatus
)的类型,但是Elasticsearch不允许直接更改已索引字段的类型。
关于为什么这个错误“不会影响 disposalstatus
字段的写入”,这主要是因为Elasticsearch在写入数据时不会重新评估或更改字段的映射。一旦数据被索引,它就被存储为与当时字段映射相匹配的形式。因此,即使你尝试更改映射并失败了,已经存在的数据(包括 disposalstatus
字段)仍然保持原样,并且新的写入操作(如果它们遵循现有的映射)仍然可以成功进行。
然而,这并不意味着你可以随意写入与当前映射不匹配的数据类型到 disposalstatus
字段。如果字段的当前类型是 text
,并且你尝试写入一个 data
类型(注意:Elasticsearch中没有内置的 data
类型,我猜测你可能是指的复杂数据类型如 object
、array
或其他JSON兼容类型)或 boolean
类型,Elasticsearch将尝试将这些数据转换为与字段映射兼容的形式。
-
对于
boolean
类型,如果disposalstatus
字段是text
类型,并且你尝试写入一个布尔值(如true
或false
),Elasticsearch将把这些值作为字符串处理,并存储在索引中。虽然查询时可能需要特别注意类型转换,但写入操作本身通常是成功的。 -
对于复杂数据类型(如
object
或array
),如果disposalstatus
字段是text
类型,并且你尝试写入一个对象或数组,Elasticsearch的行为将取决于你的Elasticsearch版本和配置。在某些情况下,它可能会尝试将这些对象或数组转换为字符串(例如,通过JSON序列化),但这通常不是最佳实践,因为这会丢失结构信息并使查询变得复杂。在较新的Elasticsearch版本中,尝试写入不兼容类型的数据可能会导致错误。
总之,错误 mapper [disposalstatus] of different type
不会影响已经存在的 disposalstatus
字段的写入(只要写入的数据类型与当前映射兼容),但它会阻止你更改字段的类型。如果你需要存储不同类型的数据,你应该考虑创建一个新字段,并在写入新数据时同时更新这两个字段。此外,对于复杂数据类型和布尔值,你应该确保字段的映射与你要存储的数据类型相匹配。
问题二:数据可以正常写入,但是能正常的查询,排序,聚合等操作吗
Fielddata is disabled on text fields by default. Set fielddata=true on [disposalstatus] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead. |
在Elasticsearch中,fielddata
默认在 text
类型的字段上是禁用的。fielddata
是一种将数据从磁盘上的倒排索引(inverted index)加载到内存中以便进行排序、聚合、脚本执行等操作的功能。但是,由于 text
字段通常包含大量文本,如果启用 fielddata
,可能会消耗大量内存,影响Elasticsearch集群的性能和稳定性。
错误信息中提到“Fielddata is disabled on text fields by default. Set fielddata=true on [disposalstatus] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead.” 是在告诉你几个关键点:
- 默认禁用:
text
字段上的fielddata
默认是禁用的。 - 启用fielddata:如果你确实需要在
disposalstatus
字段上使用fielddata
(比如进行排序或聚合操作),你可以在字段映射中设置fielddata=true
。但是,这可能会消耗大量内存。 - 使用keyword字段:作为替代方案,你可以将
disposalstatus
字段的类型更改为keyword
。keyword
类型的字段天然支持fielddata
,因为它们通常用于存储不需要全文搜索的精确值(如标签、枚举值等)。
为什么使用 keyword
字段?
- 内存使用:
keyword
字段的fielddata
消耗的内存通常比text
字段少,因为keyword
字段不包含分词(tokenization)和索引(indexing)过程中产生的额外信息。 - 性能:对于排序、聚合和脚本等需要
fielddata
的操作,keyword
字段通常能提供更好的性能。 - 用途:
keyword
字段非常适合存储不需要全文搜索的精确字符串值。
如何更改字段类型?
如果你需要更改 disposalstatus
字段的类型从 text
到 keyword
,并且该字段尚未包含大量数据,你可以通过以下步骤进行:
-
更新映射:使用Elasticsearch的映射API来更新索引的映射,将
disposalstatus
字段的类型更改为keyword
。但是,请注意,直接更改已存在字段的类型通常是不允许的。因此,你可能需要:- 删除索引并重新创建它,包含新的映射。
- 或者,如果可能的话,使用别名(alias)和索引滚动更新(rolling updates)来最小化停机时间。
- 在某些情况下,如果Elasticsearch版本和配置允许,你可以使用索引模板来为新文档设置新的字段类型,但已存在的文档不会受到影响。
-
重新索引数据(如果需要):如果你选择了删除并重新创建索引的方法,你需要将旧索引中的数据重新索引到新索引中。
-
验证更改:在更改生效后,验证新索引和映射是否符合预期,并确保应用程序可以正确地与新的索引和映射交互。
请注意,在进行此类更改之前,最好先在测试环境中验证更改的影响。
建议
- 在生产环境中,为了确保数据的结构和类型一致性,以及避免潜在的性能问题和数据不一致,强烈建议显式定义索引的映射,设置索引的动态映射策略为禁用动态映射,忽略新字段。
- 针对出现的字段映射不一致的问题,采用重建索引(reindex)的方式进行修正,避免出现存储查询排序聚合等错误。
相关文章:
Elasticsearch 映射(mapping)
概念 在 Elasticsearch 中,映射(Mapping)定义了索引中字段的类型和属性。它是索引数据结构的基础,类似于传统数据库中的表结构定义。映射不仅定义了字段的类型(如 text、keyword、integer 等)…...

开放式耳机更适合运动的时候使用?开放式耳机推荐指南
开放式耳机确实非常适合运动时使用,原因主要有以下几点。 首先,保持对外界的感知是很重要的一点。在运动的时候,我们需要听到周围的环境声音,比如车辆的行驶声、行人的呼喊等,以便及时做出反应,保证自身安全…...

食堂窗口自助点餐小程序的设计
管理员账户功能包括:系统首页,个人中心,用户管理,商家管理,店铺信息管理,菜品分类管理,菜品信息管理,订单管理,系统管理 微信端账号功能包括:系统首页&#…...
请说出路由传参和获取参数的三种方式
在Vue.js中使用Vue Router进行路由管理时,传递和获取参数是常见的需求。这里介绍三种主要的路由传参和获取参数的方式: 1. 通过URL的查询参数(Query Parameters) 传递参数: 当你需要传递一些非敏感数据(…...

精准防控,高效管理:AI智能分析网关V4区域未停留检测算法的介绍及应用
一、区域未停留AI检测算法概述 随着人工智能和计算机视觉技术的飞速发展,区域未停留AI检测算法作为一种重要的视频分析技术,逐渐在各个领域得到广泛应用。该算法通过高效处理视频流数据,能够实时分析并判断目标对象是否在预设区域内有足够的…...

html+css練習:iconfont使用
1.網址地址:https://www.iconfont.cn/search/index 2.註冊登錄,將需要的圖標添加到購物車 3.下載代碼 4.下載后的代碼有一個html頁面,裡面有詳細的使用方式...

算法导论 总结索引 | 第五部分 第二十一章:用于不相交集合的数据结构
一些应用涉及 将n个不同的元素分成一组不相交的集合。寻找包含给定元素的唯一集合 和 合并两个集合 1、不相交集合的操作 1、一个不相交集合 数据结构 维持了 一个不相交动态集的集合 S {S_1, S_2,…, S_n}。用一个代表 来标识每个集合,它是这个集合的某个成员。…...

【单例设计模式】揭秘单例模式:从原理到实战的全方位解析(开发者必读)
文章目录 深入理解单例设计模式:原理、实现与最佳实践引言第一部分:设计模式简介第二部分:单例模式定义第三部分:单例模式的优点和缺点第四部分:单例模式的实现方式懒汉式非线程安全的实现线程安全的实现(双…...

VTK8.2.0编译(Qt 5.14.2+VS2017)
VTK8.2.0编译(Qt 5.14.2VS2017) 关于Qt和MSVC的安装,可以参考文章(QtMSVC2017)。 本篇VTK在QtMSVC的配置下的编译。VTK 以8.2.0为例。 一、环境变量的配置 我们打开电脑的环境变量,可以看到没有Qt相关的…...

武汉流星汇聚:亚马逊跨境电商龙头,市场份额稳固,服务品质卓越
在全球跨境电商的版图上,亚马逊无疑是一颗璀璨的明星,以其庞大的市场规模、卓越的用户体验和强大的品牌影响力,稳居行业龙头地位。即便在诸多新兴跨境平台竞相崛起的背景下,亚马逊依然以其独特的优势,保持着难以撼动的…...

我出一道面试题,看看你能拿 3k 还是 30k!
大家好,我是程序员鱼皮。欢迎屏幕前的各位来到今天的模拟面试现场,接下来我会出一道经典的后端面试题,你只需要进行 4 个简单的选择,就能判断出来你的水平是新手(3k)、初级(10k)、中…...
opecv c++计算图像的曲率
公式 κ z x x ⋅ z y 2 − 2 ⋅ z x ⋅ z y ⋅ z x y z y y ⋅ z x 2 ( z x 2 z y 2 1 ) 3 / 2 \kappa \frac{z_{xx} \cdot z_y^2 - 2 \cdot z_x \cdot z_y \cdot z_{xy} z_{yy} \cdot z_x^2}{(z_x^2 z_y^2 1)^{3/2}}\newline κ(zx2zy21)3/2zxx⋅zy2−2⋅zx…...

鸿蒙 IM 即时通讯开发实践,融云 IM HarmonyOS NEXT 版
融云完成针对“纯血鸿蒙”操作系统的 SDK 研发,HarmonyOS NEXT 版融云 IM SDK 已上线,开发者可在“鸿蒙生态伙伴 SDK 市场”查询使用。 发挥 20 年通信行业技术积累和领创品牌效应,融云为社交、娱乐、游戏、电商、出行、医疗等各行业提供专业…...

【全国大学生电子设计竞赛】2022年D题
🥰🥰全国大学生电子设计大赛学习资料专栏已开启,限时免费,速速收藏~...

【优秀python案例】基于python爬虫的深圳房价数据分析与可视化实现
现如今,房价问题一直处于风口浪尖,房价的上涨抑或下跌都牵动着整个社会的利益,即便是政府出台各种政策方针也只能是暂时抑制楼市的涨势,对于需要买房的人来说,除了关注这些变化和政策外,还有一个非常头疼的…...

vscode安装与配置本地c/c++编译调试环境
目录 (1)安装vscode和常用插件 1.下载安装vscode 2.安装常用插件 (2)本地安装和配置编译器 1.安装编译器 2.vscode配置编译器 第1种:全局配置 第2种:为当前项目个性化配置 (3ÿ…...

PCIe学习笔记(15)
设备就绪状态 (Device Readiness Status,DRS)消息 (Device Readiness Status (DRS) 是PCIe规范中引入的一种机制,旨在改进设备初始化和就绪状态的检测与报告。 在以往的PCIe版本中,系统通常依赖于固定的超时机制来判断设备是否已…...
Rust中的特殊类型所占的内存大小
可以使用std::mem:size_of获取类型大小: use std::mem::size_of;struct Journal(String, u32); trait Summary {} impl Summary for Journal {}fn main() {println!("普通结构体相关:");println!("{}", size_of::<&Journal&…...
【深度学习】变分自编码器 VAE,什么是变分?(1)
文章目录 1. 变分自编码器 VAEVAE的基本概念VAE的数学原理编码器解码器目标函数训练过程代码示例未来发展2. 变分推断变分推断(Variational Inference)变分推断的基本概念变分推断的目标变分下界(Evidence Lower Bound, ELBO)最大化变分下界变分推断的步骤3. 必读内容1. 变…...
宏编程:C++宏、Rust宏和Lisp宏比较
根据simondobson两篇文章(1、2),总结比较一下C宏 Rust宏和Lisp宏: Rust 宏:Rust 有两种类型的宏: 声明性宏:这些模式匹配参数来生成代码。 过程宏:这些宏执行从代码到代码的更一般…...

利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...

Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...

认识CMake并使用CMake构建自己的第一个项目
1.CMake的作用和优势 跨平台支持:CMake支持多种操作系统和编译器,使用同一份构建配置可以在不同的环境中使用 简化配置:通过CMakeLists.txt文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本…...
【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?
FTP(File Transfer Protocol)本身是一个基于 TCP 的协议,理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况,主要原因包括: ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...