目录
1. 自动映射: dynamic field mapping
官方文档
一. 映射的含义和作用
1. 概念: Mapping也称之为映射,定义了ES的索引结构、字段类型、分词器等属性,是索引中必不可少的组成部分。
ES中的Mapping类似于Mysql中的表结构,当然也仅仅是类似,不是完全相同的概念。
2. maping示例
#查看product索引的mapping信息,命令如下:
GET /product/_mapping
#输出mapping
{
"test" : {
"mappings" : {
"properties" : {
"age" : {
"type" : "long"
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
可以看到 名为test索引的mapping包含2个字段:
- name, 字段类型为text, 子字段为keyword
- age, 字段类型为long
二. 字段类型
名称 | 说明 | 备注 |
数字类型 | ||
long | 64位有符号整型 | |
integer | 32位有符号整型 | |
short | 16位有符号整型 | |
byte | 8位有符号整型 | |
double | 双精度64位浮点类型 | |
float | 单精度64位浮点类型 | |
half_float | 半精度64位浮点类型 | |
scaled_float | 缩放类型浮点数, 按固定double比例因子缩放 | |
unsigned_long | 无符号64位整数 | |
基本数据类型 | ||
binary | Base64字符串二进制值 | |
boolean | 布尔类型 | |
alias | 字段别名 | |
Keyword类型 | ||
keyword | 适用于索引结构化的字段。可以用于过滤、排序、聚合。keyword字段只能通过精确值搜索到。 | |
constant_keyword | 始终包含相同值的关键字字段 | |
wildcard | 可针对类似grep | |
Date时间类型 | ||
date | 需要标准东八区时间 | |
date_nanos | 最高精度为纳秒 | |
Object对象类型 | ||
object | 非基本类型之外,默认为json对象的类型 | |
flattened | 单映射对象类型,其值为json | |
nested | 嵌套类型 | |
join | 父子级关系类型 | |
空间数据类型 | ||
geo_point | 经纬度点 | |
geo_shape | 复杂的形状,例如多边形 | |
point | 任意笛卡尔点 | |
shape | 任意笛卡尔几何 | |
文档排名类型 | ||
dense_vector | 记录浮点值的密集向量 | |
rank_feature | 记录数字特征以提高查询时的命中率 | |
文本搜索类型 | ||
text | 文本类型 | |
annotated-text | 包含特殊文本标记,用于表示命名实体 | |
completion | 用于自动补全, 即搜索推荐 | |
search_as_you_type | 类似文本的字段,经过优化为提供按类型完成的查询提供现成的支持用例 | |
token_count | 文本中的标记计数 |
三. 映射类型
1. 自动映射: dynamic field mapping
1.1 概念:
自动映射是ES会根据你给定的字段自动创建映射(mapping),ES和关系型数据库最典型的一个区别就是, 比如Mysql我们在写入数据之前, 必须创建表,手动创建表结构,指定字段名称、字段类型、字段长度等。但是ES如果没有创建索引或mapping,那么在我们插入数据时,ES会根据字段值给定字段类型。
一般来说在工作中,特别是生产环境,应尽可能避免使用dynamic自动映射,原因是ES无法根据你的业务场景给出准确的字段类型,并且索引的mapping一旦创建即无法修改,因此我们在实际工作中使用mapping应尽可能去调研好每个字段的类型, 然后手动映射参数和字段。
字段类型 | dynamic |
true/false | boolean |
小数 | float |
数字 | long |
对象 | object |
数组 | 数组,类型取决于第一个非空元素的类型 |
日期格式字符串 | date (必须为国际标准时间) |
数字类型字符串 | float/long |
字符串 | text+keyword |
1.2 代码讲解
1. 插入一条数据
#首先我们直接在dynamic_mapping索引中添加一条数据
#此时dynamic_mapping索引并不存在
PUT /dynamic_mapping/_doc/1
{
"name": "自动映射",
"small_number": 0.1,
"number": 10,
"number_string": "100"
}
2. 查看映射
#查询dynamic_mapping
GET /dynamic_mapping/_mapping
#结果
{
"dynamic_mapping" : {
"mappings" : {
"properties" : {
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"number" : {
"type" : "long"
},
"number_string" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"small_number" : {
"type" : "float"
}
}
}
}
}
可以看到, 每个字段都被ES自动赋予了类型:
- name: 文本类型text, 字段段位keyword(一般自动映射文本类型都会有子字段)
- number: 长数字类型 long
- small_number: 浮点数类型 float
- number_string: 文本类型text, 字段段位keyword
2. 手动(显示)映射:
2.1 概念:
与自动映射相反, 手动映射就是在写入数据之前, 创建索引并且手动指定包含的字段名及字段类型。创建完成后写入数据时就需要符合映射。
2.2 代码示例
#手动指定mapping
PUT /manual_mapping
{
"mappings": {
"properties": {
"name": {
"type": "text",
"fields": {
"keyword":{
"type": "keyword"
}
}
},
"number": {
"type": "integer"
},
"small_number": {
"type": "double"
},
"number_string": {
"type": "keyword"
}
}
}
}
#查询mapping
GET /manual_mapping/_mapping
#结果
{
"manual_mapping" : {
"mappings" : {
"properties" : {
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword"
}
}
},
"number" : {
"type" : "integer"
},
"number_string" : {
"type" : "keyword"
},
"small_number" : {
"type" : "double"
}
}
}
}
}
可以看到与自动映射异同:
- name: 相同
- number: 自动映射为long, 手动映射为integer
- small_number: 自动映射为float, 手动映射为double
- number_string: 自动映射为text+keyword, 手动映射为 keyword
四. 映射参数
- index: 是否对创建的当前字段建立倒排索引, 默认为true。如果不创建索引,该字段不会通过索引被搜索到,但仍然会在source元数据中展示。
我们创建一个索引test_param_index,index_test字段的index参数设置为false,并插入一条数据。可以发现无法通过该字段进行检索。
- analyzer:指定分词器。并且使用的字段必须是可分词类型。
- boost:对当前字段相关度的评分权重,默认为1。
首先我们创建一个索引, 有两个字段. test_boost的boost参数为2, test不设置此参数.
以相同的查询参数分别查询两个字段, 可以发现test_boots的评分为test的两倍
- coerce:是否允许强制类型转换
- copy_to:该参数允许将多个字段的值复制到组字段中,然后将其作为单个字段进行查询
- doc_values:为了提升排序效率,默认为true。如果确定不需要对字段进行排序或聚合,也不需要通过脚本访问字段值,则可以禁用doc值以节省磁盘(不支持text和annotated_ext)。
- dynamic: 控制是否可以动态添加新字段。
- true: 新检测到的字段将添加到映射中去(默认)。
- false: 新检测到字段将被忽略。这些字段将不会被索引,因为将无法搜索,但仍会出现在_source返回的匹配项中。这些字段不会被添加到映射中,必须显示新增映射字段。
- strict:如果检测到新字段,则会引发异常并拒绝文档。必须将新字段显示映射
- eager_global_ordinals:用于聚合字段上,优化聚合性能,但不适用于冻结索引上
- enable:是否创建倒排索引,可以对字段操作,也可以对索引操作。如果不创建索引, 仍然可以检索和在_source数据中展示,谨慎使用,该状态无法修改。
- fielddata: 查询时内存数据结构,在首次使用当前字段聚合、排序、或者在脚本中使用时,需要字段为fielddata结构, 并且创建倒排索引到堆中。
- fields:给字段创建多个字段, 用于不同目的。一般来说text类型都会创建keyword的子字段。
- format: 格式化
PUT /data_format
{
"mappings": {
"properties": {
"date": {
"type": "date",
"format": ["yyyy-MM-dd HH:mm:ss"]
}
}
}
}
- ignore_above:超过长度将会被忽略
- ignore_malformed:忽略类型错误
- index_option:控制将哪些信息添加到反向索引中以进行搜索和突出显示。仅用于text字段
- index_phrases:提升exact_value查询速度,但要消耗更多的磁盘空间。
- index_prefixes: 前缀搜索
- min_chars: 前缀最小长度,默认为2
- max_chars: 前缀最大长度,默认为5
- meta:附加元数据
- norms:是否禁用评分。(在filter和聚合字段上应该禁用)
- null_value: 为null值赋予默认值
- proterties:除了mapp还可以用于object的属性设置
- search_analyzer:用于单独设置查询时分析器。
- similarity: 为字段设置相关度算法, 支持BM25,classic,boolean。
- store: 设置是否字段为仅查询
- term_vector:运维相关参数。
五. 自动映射模版 Dynamic template
1. 概念:
如果我们想要使用自动映射, 并且希望自动映射可以按照我们的需求来定义字段类型的话, 我们就可以使用 Dynamic template 来完成。通过模版设定规则来实现我们的业务需求
2. 官方代码示例
#创建模板
PUT my-index-000001
{
"mappings": {
"dynamic_templates": [
{
"longs_as_strings": {
"match_mapping_type": "string",
"match": "long_*",
"unmatch": "*_text",
"mapping": {
"type": "long"
}
}
}
]
}
}
#写入一条数据
PUT my-index-000001/_doc/1
{
"long_num": "5",
"long_text": "foo"
}
模板内容解析:
1. match_mapping_type: 字段内容类型需要匹配
2. match: 字段名称需要匹配该条件
3. unmatch: 字段名称不能匹配该条件
4. mapping:若符合的话将字段映射为目标类型