Elasticsearch:Mapping
概述#
- Mapping定义了文档(document)及其包含的字段(filed)在存储和被索引时的过程和方式。
- 每个文档都是一组字段的集合,而每个字段也有自己的数据类型。Mapping中不仅包含了与文档相关的字段列表,还包括元数据字段(例如_source),因此可以自定义文档相关元数据的处理方式。
- Mapping有Dynamic(动态生成)和Explicit(显式指定)两种实现方式,可根据字段的特点配合使用。
Dynamic Mapping#
我们只需创建一条文档并指定其所在索引,Dynamic Mapping便会为我们自动生成索引、字段以及字段类型。
PUT /my_index/_doc/first_doc
{
"num": 5,
"text": "5"
}
查看该索引的Mapping,我们发现字段值为数字的num
字段的类型自动映射为long类型。而text
字段映射为了text类型,其子字段tex.keyword
类型则为keyword,可用于排序和聚合等操作(详见:https://www.elastic.co/guide/en/elasticsearch/reference/current/multi-fields.html)。
GET /my_index/_mapping
// 返回
{
"my_index" : {
"mappings" : {
"properties" : {
"num" : {
"type" : "long"
},
"text" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
但大多数情况下,我们可能希望值为"123"和"2021/02/26"这样的字段能够分别映射为long和date类型,这时便需要对Dynamic Mapping的方式进行自定义。
Dynamic field mappings#
当我们将mappings.dynamic
属性设置为true
或runtime
后,便可以增加Dynamic Mapping的映射规则。值得一提的是,runtime
这种Mapping方式仍处于beta测试中。
Json数据类型 | mappings.dynamic: true |
mappings.dynamic: runtime |
---|---|---|
null | 不添加该字段 | 不添加该字段 |
true or false | bool | bool |
double | float | double |
integer | long | long |
object | object | object |
array | 由数组第一个非空值的类型决定 | 由数组第一个非空值的类型决定 |
检测为日期的string | date | date |
检测为数字的string | float or long | double or long |
其他string | 带有.keyword子字段的text | keyword |
对于数据类型为object的字段,在两种规则下都会将其包含的多个字段映射在mappings.properties.<object-filed>.properties
中。我们以mappings.dynamic: true
为例,检验Dynamic Mapping的处理方式。由于数字检测是默认关闭的(日期检测默认开启),因此还要先对索引的Mapping进行相关设置:
PUT /my_index/
{
"mappings": {
"dynamic": true,
"numeric_detection": true
}
}
然后在不指定Mapping的情况下向索引中加入一个文档:
PUT /my_index/_doc/1
{
"one": null,
"two": true,
"three": 1.11111111111111111111,
"four": 1,
"five": {
"one": "3",
"two" : "true"
},
"six": "2021/02/26",
"seven": "1",
"eight" : "koktlzz"
}
随后即可查看该索引中各字段的类型:
GET /my_index/_mapping
// 返回
{
"my_index" : {
"mappings" : {
"dynamic" : "true",
"numeric_detection" : true,
"properties" : {
"eight" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"five" : {
"properties" : {
"one" : {
"type" : "long"
},
"two" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
},
"four" : {
"type" : "long"
},
"seven" : {
"type" : "long"
},
"six" : {
"type" : "date",
"format" : "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"
},
"three" : {
"type" : "float"
},
"two" : {
"type" : "boolean"
}
}
}
}
}
Dynamic template#
我们还可以通过模板(Dynamic template)进一步地自定义索引字段的Mapping方式,而模板与字段的匹配规则有以下三种:
match_mapping_type
:匹配字段的数据类型;match
和unmatch
:匹配字段的名称;path_match
和path_unmatch
:匹配字段的全路径(如<object>.*.<filed>
)。
一个典型的Dynamic template的基本配置如下:
"dynamic_templates": [
{
"dynamic_template_name": {
... match conditions ... // 使用上述三种规则匹配相关字段
"mapping": { ... } // 指定匹配字段的Mapping方式
}
},
...
]
我们使用一个复杂的模板为例,展示Dynamic template对字段的映射方式:
PUT my_index
{
"mappings": {
"dynamic_templates": [{
"longs_as_strings": {
"match_mapping_type": "string",
"match": "long_*",
"unmatch": "*_text",
"mapping": {
"type": "long"
}
}
}, {
"full_name": {
"path_match": "name.*",
"path_unmatch": "*.middle",
"mapping": {
"type": "text"
}
}
}]
}
}
该模板规定了两种匹配规则:名称以"long"开头、不以"text"结尾且类型为string的字段将会被映射为long类型;name
对象中除middle
外的字段将会被映射为text类型:
PUT my_index/_doc/1
{
"long_num": "5",
"long_text": "foo",
"name": {
"first": "John",
"middle": "Winston"
}
}
GET /my_index/_mapping
// 返回
{
...
"properties" : {
"long_num" : {
"type" : "long"
},
"long_text" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"name" : {
"properties" : {
"first" : {
"type" : "text"
},
"middle" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
Explicit Mapping#
除了让Elasticsearch为我们动态生成Mapping外,我们当然也可以显式地指定索引中各字段的Mapping方式,如:
PUT /my_index
{
"mappings": {
"properties": {
"age": { "type": "integer" },
"email": { "type": "keyword" },
"name": { "type": "text" }
}
}
}
对于一个已定义Mapping的索引,我们无法更新其中已存在的字段Mapping方式,但是可以增加字段。相比于创建,PUT请求的URL多了一个"/_mapping":
PUT /my_index/_mapping
{
"properties": {
"employee-id": {
"type": "keyword"
}
}
}
之前我们使用了GET /my_index/_mapping的方式查看索引中的Mapping。而如果只想了解其中几个特定字段的Mapping,可以这样做:
GET /my_index/_mapping/field/employee-id
// 返回
{
"my_index" : {
"mappings" : {
"employee-id" : {
"full_name" : "employee-id",
"mapping" : {
"employee-id" : {
"type" : "keyword"
}
}
}
}
}
}
除了上述的基本数据类型外,Elasticsearch还支持多种数据类型,详见官方文档。而除了通常用来存储数据的字段外,每个文档还包含一些元数据字段,如_source
字段保存了文档内容的原始JSON文件。
Mapping parameters#
在字段的Mapping规则中,我们可以添加一些参数从而让字段的搜索结果更加符合我们的预期。详见官方文档,此处介绍几个相对重要的Mapping参数:
- index:默认为true,代表是否对该字段进行Text Analysis。若设置为false,则只能通过完全匹配搜索到。常用于对时间序列字段的设置中;
- enable:默认为true,代表该字段是否被索引。若设置为false,则完全不会被搜索到且不会影响文档的评分,只能在
_source
中找到该字段; - norms:默认为true,代表该字段是否参与评分。若设置为false,则可以减少磁盘占用;
- doc_value:默认为true。若设置为false,则无法对该字段进行排序、聚合和脚本访问等操作;
- filedata:默认为false,代表是否对排序、聚合和脚本访问等操作进行优化。若设置为true,则会占用大量内存;
- store:默认为false,代表数据的存储方式,可以将经常被搜索且较小字段的store参数设置为true来单独存储。相比从
_source
中搜索,这样设置可以减少IO操作,从而提高效率;
作者:koktlzz
出处:https://www.cnblogs.com/koktlzz/p/14521571.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现