索引库-mapping

写在前面的话:

在 Elasticsearch 6.x 及之前,每个索引中可以包含多个“类型”(类似于 SQL 中的表),通过类型区分不同文档结构。

从 Elasticsearch 7.x 开始,移除了类型的概念,所有文档在一个索引中共享相同的映射(mapping)。也就是说,不能再通过 type 区分不同文档,而是直接使用索引级别的映射。

Elasticsearch 8.x 彻底移除了类型字段,即 _type 字段完全不存在。

在 Elasticsearch 7.x 及以上版本中,索引结构的基础已经从原来的“类型(type)”转变为纯粹基于文档和字段(document and field)

mapping 是对索引库中 document 的约束,本文介绍常见的mapping属性

常见的mapping属性

  • type(字段类型)

  • index(是否创建索引,默认true)

  • analyzer(分词器)

  • properties(该字段有哪些子字段)

type 类型详解

核心数据类型

文本类型 text

文本类型默认会被分词,可以指定 index:"false",令其不分词

关键字类型 keyword

关键字类型默认不分词,但可以指定 index:"true",令其分词

数值类型

类型 说明
byte 有符号的8位整数, 范围: [-128 ~ 127]
short 有符号的16位整数, 范围: [-32768 ~ 32767]
integer 有符号的32位整数, 范围: [−231−231 ~ 231231-1]
long 有符号的64位整数, 范围: [−263−263 ~ 263263-1]
float 32位单精度浮点数
double 64位双精度浮点数
half_float 16位半精度IEEE 754浮点类型
scaled_float 缩放类型的的浮点数, 比如price字段只需精确到分, 57.34缩放因子为100, 存储结果为5734

实战:尽可能选择小的数据类型,字段长度越小,索引和搜索的效率越高

为什么需要 scaled_float ?

答:高效存储浮点数并保持一定精度。

如何使用 scaled_float ?

答:指定缩放因子为 100 的写法

1
2
3
4
5
6
7
8
9
10
11
PUT /products
{
"mappings": {
"properties": {
"price": {
"type": "scaled_float",
"scaling_factor": 100
}
}
}
}

日期类型 date

JSON 本身没有 date 类型,在 ES 中,日期可以是:

  • 包含格式化日期的字符串, “2018-10-01”, 或”2018/10/01 12:10:30”.

  • 代表时间毫秒数的长整型数字.

  • 代表时间秒数的整数.

可以自定义日期格式, 若未指定, 则使用默认格式: strict_date_optional_time||epoch_millis

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 添加映射
PUT website
{
"mappings": {
"blog": {
"properties": {
"pub_date": {"type": "date"} // 日期类型
}
}
}
}

// 添加数据
PUT website/blog/11
{ "pub_date": "2018-10-10" }

PUT website/blog/12
{ "pub_date": "2018-10-10T12:00:00Z" } // Solr中默认使用的日期格式

PUT website/blog/13
{ "pub_date": "1589584930103" } // 时间的毫秒值

如果有多种格式,可以使用 || 分开,会从前往后依次尝试匹配

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 添加映射
PUT website
{
"mappings": {
"blog": {
"properties": {
"date": {
"type": "date", // 可以接受如下类型的格式
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
}
}
}

布尔类型 boolean

真值(true)的转换

以下值在 Elasticsearch 中可以被自动解析为 true

  • **true**:布尔值 true
  • **"true"**:字符串 "true"
  • **1**:数字 1
  • **"1"**:字符串 "1"
假值(false)的转换

以下值在 Elasticsearch 中可以被自动解析为 false

  • **false**:布尔值 false
  • **"false"**:字符串 "false"
  • **0**:数字 0
  • **"0"**:字符串 "0"
  1. 这个转换得关注具体的版本或者特殊处理。如果是ES不支持的转换,将会报错
  2. boolean 可以是 null,此时认为该字段缺失,既不是 true 也不是 false

二进制 binary

二进制类型代表的是Base64编码字符串的二进制值(存储前要转Base64编码),一般用于存储图片、文件等非文本数据,不能被搜索

范围类型 range

类型 范围
integer_range −231−231 ~ 231−1231−1
long_range −263−263 ~ 263−1263−1
float_range 32位单精度浮点型
double_range 64位双精度浮点型
date_range 64位整数, 毫秒计时
ip_range IP值的范围, 支持IPV4和IPV6, 或者这两种同时存在

关于数组

ES中没有专门的数组类型, 直接使用[]定义即可;

数组中所有的值必须是同一种数据类型, 不支持混合数据类型的数组:

① 字符串数组: [“one”, “two”];
② 整数数组: [1, 2];
③ 由数组组成的数组: [1, [2, 3]], 等价于[1, 2, 3];
④ 对象数组: [{“name”: “Tom”, “age”: 20}, {“name”: “Jerry”, “age”: 18}].

注意:

  • 动态添加数据时, 数组中第一个值的类型决定整个数组的类型;
  • 不支持混合数组类型, 比如[1, “abc”];
  • 数组可以包含null值, 空数组[]会被当做missing field —— 没有值的字段.