Elasticsearch 字段类型详解:从基础到高级应用
Elasticsearch 提供了丰富的字段类型,每种类型对应特定的数据结构和使用场景,直接影响索引效率、查询性能和功能支持。以下是 6.8.x 版本中常用字段类型的详细解析,包括适用场景、特性及配置示例。
字符串类型:text 与 keyword
字符串是最常用的字段类型,Elasticsearch 将其细分为 text(全文本) 和 keyword(关键字),以满足不同的检索需求。
text(全文本类型)
特性:
- 会被分词器处理(拆分为词项),支持全文检索(如 “苹果手机” 可拆分为 “苹果”“手机”,匹配包含任一词项的文档)。
- 不适合排序、聚合(分词后的值分散,无法高效分组)。
适用场景:需要全文搜索的长文本,如商品描述、文章正文、评论内容等。
配置示例:
1
2
3
4
5
6
7
8
9{
"mappings": {
"default": {
"properties": {
"product_description": { "type": "text" } // 全文搜索商品描述
}
}
}
}
keyword(关键字类型)
特性:
- 不分词,将整个字符串作为一个词项(如 “苹果手机” 会被视为单个词项,仅精确匹配时命中)。
- 适合过滤(
term
查询)、排序(sort
)、聚合(terms
分组)。
适用场景:结构化字符串,如标签、状态、ID、分类等。
配置示例:
1
2
3
4
5
6
7
8
9
10{
"mappings": {
"default": {
"properties": {
"product_tag": { "type": "keyword" }, // 标签用于过滤和聚合
"order_id": { "type": "keyword" } // 订单号用于精确查询
}
}
}
}
进阶:多字段(text + keyword)
对于既需要全文检索又需要排序 / 聚合的字段(如商品名称),可通过 多字段(multi-fields) 同时定义 text 和 keyword 类型:
1 | { |
- 查询时:用
product_name
进行全文搜索,用product_name.keyword
进行精确匹配或聚合。
数字类型
Elasticsearch 支持多种数字类型,选择合适的类型可减少存储空间并提高查询效率。
类型 | 范围 | 适用场景 |
---|---|---|
long |
-2^63 ~ 2^63-1 | 大整数(如订单量、用户数) |
integer |
-2^31 ~ 2^31-1 | 中等整数(如年龄、数量) |
short |
-32768 ~ 32767 | 小整数(如评分、状态码) |
byte |
-128 ~ 127 | 极小整数(如性别:0/1) |
double |
64 位双精度浮点数 | 高精度小数(如价格、坐标) |
float |
32 位单精度浮点数 | 普通精度小数(如权重) |
half_float |
16 位半精度浮点数 | 低精度场景(如概率) |
scaled_float |
基于长整数的缩放浮点数(需指定 scaling_factor ) |
货币(如 scaling_factor:100 表示保留两位小数) |
配置示例:
1 | { |
日期类型(date)
日期类型支持多种格式,可自动识别或显式指定,适合时间范围查询、排序等场景。
特性
- 内部存储为长整数(毫秒级时间戳),查询时自动转换为可读性格式。
- 支持的格式:
"yyyy-MM-dd"
、"yyyy/MM/dd HH:mm:ss"
、"epoch_millis"
(时间戳)等。
配置示例
1 | { |
查询示例:
1
{ "query": { "range": { "publish_time": { "gte": "2023-01-01", "lte": "now" } } }
布尔类型(boolean)
用于存储 true
或 false
,适合表示开关、状态等二值属性。
配置示例:
1 | { |
范围类型
范围类型用于存储数值或日期的区间,支持范围包含查询(如判断某个值是否在范围内)。
类型 | 描述 |
---|---|
integer_range |
整数范围(如 {"gte":18, "lte":30} ) |
float_range |
浮点数范围 |
long_range |
长整数范围 |
double_range |
双精度浮点数范围 |
date_range |
日期范围(如 {"gte":"2023-01-01", "lte":"2023-12-31"} ) |
ip_range |
IP 地址范围(如 {"gte":"192.168.0.0", "lte":"192.168.255.255"} ) |
配置示例:
1 | { |
查询示例(匹配年龄在 18-30 范围内的文档):
1
{ "query": { "term": { "age_range": { "value": 25 } } } }
数组类型(array)
Elasticsearch 不单独定义数组类型,任何字段都可存储数组,只需确保数组元素类型一致。
特性
- 数组元素必须为同一类型(如字符串数组
["a", "b"]
、整数数组[1, 2]
)。 - 无需显式配置,写入时直接传入数组即可。
示例:
1 | // 文档示例(tags为字符串数组,scores为整数数组) |
查询数组中包含 “科技” 的文档:
1
{ "query": { "term": { "tags": "科技" } } }
对象类型(object 与 nested)
用于存储 JSON 对象或对象数组,两者的区别在于是否支持独立查询对象内部字段。
object(对象类型)
- 特性:用于存储单个 JSON 对象,内部字段会被扁平化为顶级字段(如
user.name
)。 - 局限:对象数组中的字段会被 “扁平化合并”,无法区分不同对象的属性(如无法查询 “name 为 A 且 age 为 20” 的对象)。
配置示例:
1 | { |
nested(嵌套类型)
- 特性:用于存储对象数组,每个对象会被视为独立文档索引,支持对对象内部字段进行关联查询。
- 适用场景:需要查询对象数组中满足 “多字段组合条件” 的场景(如 “作者为张三且评分 > 4.5 的书籍”)。
配置示例:
1 | { |
查询示例(查询 books 数组中作者为 “张三” 且评分 > 4.5 的文档):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15{
"query": {
"nested": {
"path": "books", // 指定嵌套对象路径
"query": {
"bool": {
"must": [
{ "term": { "books.author": "张三" } },
{ "range": { "books.score": { "gt": 4.5 } } }
]
}
}
}
}
}
地理类型
用于存储地理位置信息,支持距离查询、区域过滤等地理相关操作。
geo_point(地理点类型)
- 特性:存储经纬度坐标(如
{"lat": 39.9, "lon": 116.3}
),支持距离排序、范围查询。
配置示例:
1 | { |
查询示例(查找距离北京天安门(39.9042, 116.4074)10 公里内的地点):
1
2
3
4
5
6
7
8{
"query": {
"geo_distance": {
"distance": "10km",
"location": { "lat": 39.9042, "lon": 116.4074 }
}
}
}
geo_shape(地理形状类型)
- 特性:存储复杂地理形状(如多边形、圆形),支持判断点是否在形状内、形状是否相交等操作。
其他常用类型
类型 | 描述 | 适用场景 |
---|---|---|
ip |
存储 IPv4 或 IPv6 地址,支持范围查询 | 日志中的 IP 地址、设备 IP |
completion |
提供自动补全建议,支持前缀匹配 | 搜索框自动提示 |
token_count |
统计字符串分词后的词项数量 | 统计文章关键词数量 |
join |
同一索引内创建父子文档关系 | 评论与文章、订单与商品的关联 |
v1.3.10