文章目录
Elasticsearch 数据类型
常见类型
- binary:接受二进制值作为 Base64编码字符串。该字段默认不存储且不可搜索,且不得嵌入换行符\n。
- boolean:布尔值,true 或 false
- keyword 关键字类型
- keyword,用于结构化内容,例如 ID、电子邮件地址、主机名、状态代码、邮政编码或标签。
- constant_keyword 静态常量关键字类型。
- wildcard 通配符关键字类型。
- 数字类型
- 整数 integer、long、short、byte
- 浮点型 float、double等,浮点型可能损失精度
- scaled_float 我们要存的值。其对应一个附加参数 scaling_factor(缩放因子)
- 比如 scaled_float = 1.23,scaling_factor = 10,那么在elastic中存储的值为 12(按整数存储,不损失精度),我们之后再取出来,值就变成了1.2。
- 如果要完整存储,那么 scaling_factor 就应该设置为100
- 日期类型
- type 为 date
- “2015-01-01” 或 “2015/01/01 12:10:30”
- 毫秒数
- 可以使用 format 参数 配置自定义格式(epoch_millis 毫秒数、yyyy-MM-dd HH:mm:ss.SSS 等符合java DateFormat的日期格式)
- format可以同时使用多一个格式中间用 || 隔开 (如:yyyy-MM-dd || yyyy-MM-dd HH:mm:ss)
- alias 别名类型
- 别名类型同时需要设置 path 参数,参数的值为对应别名的字段。字段可能是个对象调用链(object1.object2.field)
对象类型
- object 对象类型(表示该字段是一个对象类型)
- flattened 平铺字段类型,将整个对象映射为单个字段。有助于防止映射爆炸。但只支持基本的查询。
- nested 嵌套字段类型
- 例如:
{
“first” : “John”,
“last” : “Smith”
},{
“first” : “Alice”,
“last” : “White”
}
当我们查询 first:alice,last:"White"时,将不会有结果
- 例如:
- join 类型是在同一索引的文档中创建父/子关系的特殊字段。
结构化数据类型
-
范围类型,范围字段类型表示上限和下限之间的连续值范围。例如,一个范围可以表示十月的任何日期或从 0 到 9 的任何整数。它们是使用运算符 gt或gte用于下限和lt或lte用于上限定义的。它们可用于查询,但对聚合的支持有限。
- integer_range、float_range、long_range、double_range、date_range、ip_range
-
ip 字段类型(ip)存储IPv4或IPv6
-
version 版本字段类型
文本搜索类型
- text字段类型
- text,全文内容的字段类型,例如电子邮件正文或产品描述。它被索引之前会被文本分析器(分词器)进行拆分。text 字段最适合非结构化但可读的内容。
- match_only_text,一种空间优化的变体,它禁用评分,并且在需要位置的查询上执行速度较慢。它最适合索引日志消息。
聚合数据类型
- aggregate_metric_double
预先聚合的指标值。 - histogram
直方图形式的预聚合数值。
文档排名类型
- dense_vector
记录浮点值的密集向量。 - rank_feature
记录数字特征以提高查询时的命中率。 - rank_features
记录数字特征以提高查询时的命中率。
空间数据类型
- geo_point
纬度和经度点。 - geo_shape
复杂的形状,例如多边形。 - point
任意笛卡尔点。 - shape
任意笛卡尔几何。
数组
在 Elasticsearch 中,数组不需要专用的字段数据类型。默认情况下,任何字段都可以包含零个或多个值,但是,数组中的所有值必须属于相同的字段类型
映射
映射是定义文档及其包含的字段如何存储和索引的过程
动态字段映射
默认情况下,当 Elasticsearch 检测到文档中的新字段时,它会默认将该字段动态添加到类型映射中。此功能由映射的参数 dynamic 来决定,这个我们后续来详细说明。
动态字段映射类型对应表
JSON 字段类型 | “dynamic”:“true” | “dynamic”:“runtime” |
---|---|---|
null | 无对应字段 | 无对应字段 |
true/false | boolean | boolean |
double | float | double |
long | long | long |
object | object | 无对应字段 |
array | 取决于数组中第一个非null值 | 取决于数组中第一个非null值 |
string通过日期检测 | date | date |
string通过数值检测 | float或者long | float或者long |
string没有通过date检测或numeric检测 | text有一个.keyword子字段 | keyword |
date_detection 禁用日期检测
{ "mappings": { "date_detection": false } }
dynamic_date_formats 自定义动态映射的日期格式
{ "mappings": { "dynamic_date_formats": ["MM/dd/yyyy"] // 可配置多个格式 } }
numeric_detection false禁用或true启用数字检测(默认为禁用的,在某些应用中,数字会被映射成text)
{ "mappings": { "numeric_detection": true } }
动态模板映射
动态模板映射,是为了控制在默认动态字段映射规则之外映射数据。在进行索引映射的时候,通过各种条件去对应适配动态模板,但此方式也不能解决更精确的字段映射,所以此处我们就不展开说了。
显式映射
我们在日常开发使用中,我建议大家使用显式映射,以更精确的映射字段类型。更便于 elasticsearch 针对对应字段做更精确的索引分析等。
创建索引时直接映射字段
使用创建索引的API直接映射字段(关于创建索引API的说明,请查看 Elasticsearch REST API 索引管理 )
PUT /person
{
"mappings": {
"properties": {
"age": {
"type": "integer"
},
"birthday": {
"type": "date",
"format":"yyyy-MM-dd HH:mm:ss"
},
"name": {
"type": "keyword"
},
"height": {
"type": "float"
},
"id": {
"type": "long"
},
"sex":{
"type": "byte"
}
}
}
}
如果咱们不显式定义映射,那么 birthday 和 name 都会被映射为 text 类型。
更新映射 API
PUT /<target>/_mapping
路径参数
- target 索引名
查询参数
-
allow_no_indices
(可选,布尔值)如果 为false,任何通配符表达式、索引别名或值目标仅丢失或关闭索引,请求将返回错误 。例如,如果请求索引以 foo*,bar* 开头,如果有索引,以foo开头但没有索引以bar开头,则请求定位会返回错误。 默认为true. -
expand_wildcards
(可选,字符串)通配符模式可以匹配的索引类型。支持逗号分隔值,例如open,hidden。默认为open.可选值为: -
all
匹配任何数据流或索引,包括隐藏的。 -
open
匹配开放的、非隐藏的索引。也匹配任何非隐藏数据流。 -
closed
匹配封闭的、非隐藏的索引。也匹配任何非隐藏数据流。数据流无法关闭。 -
hidden
匹配隐藏的数据流和隐藏的索引。open必须与、 closed或两者 结合使用。 -
none
不接受通配符模式。 -
ignore_unavailable
(可选,布尔值)false,如果请求针对丢失或关闭的索引,则请求返回错误。默认为false. -
local
(可选,布尔值)true,则请求仅从本地节点检索信息。默认为false,这意味着信息是从主节点检索的。 -
master_timeout
(可选,时间单位)等待连接到主节点的时间。如果在超时到期之前未收到响应,则请求失败并返回错误。默认为 30s.
请求正文
properties
(必填,映射对象)字段的映射。对于新字段,此映射可以包括:
- 字段名称
- 字段数据类型
- 映射参数
示例:添加新的映射字段
PUT /person/_mapping
{
"properties":{
"weight": {
"type": "float"
}
}
}
示例:为object类型字段添加新字段
PUT /person/_mapping
{
"properties":{
"child": {
"properties": {
"name": {
"type": "keyword"
}
}
}
}
}
示例:修改已有的映射字段
注:此操作要谨慎操作,更改现有字段可能会使已编制索引的数据无效。必须要修改,修改之后需要重新索引。
如:把我们刚刚添加的新字段映射类型修改为 keyword
PUT /person/_mapping
{
"properties":{
"weight": {
"type": "keyword"
}
}
}
修改之后,我们需要重新索引(请查看上一篇文章 Elasticsearch REST API 文档管理)
获取映射API
GET /_mapping
GET /<target>/_mapping
路径参数
- target
(可选,字符串)用于限制请求的数据流、索引和别名的逗号分隔列表。
查询参数
-
allow_no_indices
(可选,布尔值)如果 为false,任何通配符表达式、索引别名或值目标仅丢失或关闭索引,请求将返回错误 。例如,如果请求索引以 foo*,bar* 开头,如果有索引,以foo开头但没有索引以bar开头,则请求定位会返回错误。 默认为true. -
expand_wildcards
(可选,字符串)通配符模式可以匹配的索引类型。支持逗号分隔值,例如open,hidden。默认为open.可选值为: -
all
匹配任何数据流或索引,包括隐藏的。 -
open
匹配开放的、非隐藏的索引。也匹配任何非隐藏数据流。 -
closed
匹配封闭的、非隐藏的索引。也匹配任何非隐藏数据流。数据流无法关闭。 -
hidden
匹配隐藏的数据流和隐藏的索引。open必须与、 closed或两者 结合使用。 -
none
不接受通配符模式。 -
ignore_unavailable
(可选,布尔值)false,如果请求针对丢失或关闭的索引,则请求返回错误。默认为false. -
local
(可选,布尔值)true,则请求仅从本地节点检索信息。默认为false,这意味着信息是从主节点检索的。 -
master_timeout
(可选,时间单位)等待连接到主节点的时间。如果在超时到期之前未收到响应,则请求失败并返回错误。默认为 30s.
示例:查询映射
GET /person/_mapping
示例:查询所有映射
GET /*/_mapping
GET /_all/_mapping
GET /_mapping
映射参数
dynamic 是否动态映射
作用于文档或文档的内部对象
示例
PUT /person
{
"mappings": {
"dynamic": false,
"properties": {
"user": {
"properties": {
"name": {
"type": "text"
},
"car": {
"dynamic": true,
"properties": {}
}
}
}
}
}
}
该映射表示,我们的文档第一层的字段,只有user,新增的字段将不不会被索引或搜索,而user字段对象,car对象的字段可以动态新增并添加到映射。
dynamic 可接收的参数
- true
新字段添加到映射(默认)。 - runtime
新字段作为运行时字段 添加到映射中。这些字段没有索引,在_source在查询时加载。 - false
忽略新字段。这些字段不会被索引或搜索,但仍会出现在_source返回的命中字段中。这些字段不会添加到映射中,必须显式添加新字段。 - strict
如果检测到新字段,则会抛出异常并拒绝文档。
coerce 强制转换(数字类型)
如果设置为true(默认为true)elasticsearch 将会自动转换我们在创建文档时传入的值:
- 将字符强制转换为数字
- 如果映射类型为整型,但传入了浮点型,浮点数将会被截断
示例
PUT my-index-000001
{
"mappings": {
"properties": {
"number_one": {
"type": "integer"
},
"number_two": {
"type": "integer",
"coerce": false
}
}
}
}
PUT my-index-000001/_doc/1
{
"number_one": "10"
}
PUT my-index-000001/_doc/2
{
"number_two": "10"
}
number_one 的 10 会被转换为整型,但 number_two 文档会报错无法新增。
在索引级别使用 index.mapping.coerce 设置
PUT my-index-000001
{
"settings": {
"index.mapping.coerce": false
},
"mappings": {
"properties": {
"number_one": {
"type": "integer",
"coerce": true
},
"number_two": {
"type": "integer"
}
}
}
}
使用索引的settings来设置index.mapping.coerce,禁用自动强制类型转换。
analyzer 指定文本分析器
指定的分析器用于索引和搜索分析
关于分析器的具体功能,我们将在后续文章中单独讲解。
search_analyzer
同 analyzer 只不过是其只指定 用于搜索的分析器。
注:一般情况下用于索引和搜索的分析器应该为同一个,所以只指定analyzer 即可。
copy_to 复制字段
copy_to 可以将多个字段的值复制到一个组字段中,然后可以将其作为单个字段进行查询。
示例
PUT my-index-000001
{
"mappings": {
"properties": {
"first_name": {
"type": "text",
"copy_to": "full_name"
},
"last_name": {
"type": "text",
"copy_to": "full_name"
},
"full_name": {
"type": "text"
}
}
}
}
PUT my-index-000001/_doc/1
{
"first_name": "John",
"last_name": "Smith"
}
GET my-index-000001/_search
{
"query": {
"match": {
"full_name": {
"query": "John Smith",
"operator": "and"
}
}
}
}
enabled 禁用对象字段
elasticsearch 默认情况下,会为我们添加的字段添加索引,如果我们只想存储字段而不对其建立索引。可以使用 enabled 参数
注:enabled 只能作用于 索引级别或文档中的object字段
PUT /index
{
"mappings": {
"enabled": true,
"properties": {
"name": {
"type":"keyword"
},
"car":{
"type": "object",
"enabled":false
}
}
}
}
format 日期格式化
日期格式化的格式遵循Java的日期格式化格式,如:yyyy-MM-dd HH:mm:ss.SSS。我们在文档管理的示例中已经添加过了。
ignore_above、ignore_malformed
ignore_above 数字类型,比如:20.表示字符串超过相应长度,将不被索引。
ignore_malformed 正常情况下,日期类型不正确或数字类型不正确,将忽略此字段,而且文档的其他字段会正常存储。如果设置为false,则如果出现日期类型不正确将会导致整个文档添加失败。
fields
为不同的目的以不同的方式索引同一个字段, string 字段可以映射为 text 用于全文搜索,也可以映射为 keyword 用于排序或聚合
PUT my-index-000001
{
"mappings": {
"properties": {
"city": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
}
}
}
}
PUT my-index-000001/_doc/1
{
"city": "New York"
}
PUT my-index-000001/_doc/2
{
"city": "York"
}
GET my-index-000001/_search
{
"query": {
"match": {
"city": "york"
}
},
"sort": {
"city.raw": "asc"
},
"aggs": {
"Cities": {
"terms": {
"field": "city.raw"
}
}
}
}
null_value 空值
null_value 将显式值替换null为指定值,以便对其进行索引和搜索。
PUT my-index-000001
{
"mappings": {
"properties": {
"status_code": {
"type": "keyword",
"null_value": "NULL"
}
}
}
}
此示例我们将null值映射为 “NULL” 字符串
store
是否将数据进行独立存储,默认为 false
原始的文本会存储在_source 里面,默认情况下其他提取出来的字段都不是独立存储的,是从_source 里面提取出来的。当然你也可以独立的存储某个字段,只要设置"store": true 即可,获取独立存储的字段要比从_source 中解析快得多,但是也会占用更多的空间,所以要根据实际业务需求来设置。