跳到主要内容

Elasticsearch 数据类型

Elasticsearch 是一个强大的分布式搜索和分析引擎,支持多种数据类型。理解这些数据类型是使用 Elasticsearch 的基础,因为它们决定了如何存储、索引和查询数据。本文将详细介绍 Elasticsearch 支持的主要数据类型,并通过实际案例展示它们的应用场景。

1. 核心数据类型

Elasticsearch 的核心数据类型是最常用的数据类型,适用于大多数场景。以下是几种常见的核心数据类型:

1.1 字符串类型(Text 和 Keyword)

  • Text:用于全文搜索的字符串类型。Text 类型会对文本进行分词处理,适合存储需要被搜索的长文本(如文章内容)。
  • Keyword:用于精确匹配的字符串类型。Keyword 类型不会对文本进行分词,适合存储不需要分词的短文本(如标签、状态码)。
json
{
"mappings": {
"properties": {
"title": {
"type": "text"
},
"tags": {
"type": "keyword"
}
}
}
}

示例

  • 输入:{"title": "Elasticsearch 入门指南", "tags": ["search", "database"]}
  • 输出:title 字段会被分词,而 tags 字段会作为整体存储。
提示

如果需要同时支持全文搜索和精确匹配,可以为同一个字段同时定义 textkeyword 类型。

1.2 数值类型(Numeric)

Elasticsearch 支持多种数值类型,包括:

  • long:64 位整数。
  • integer:32 位整数。
  • short:16 位整数。
  • byte:8 位整数。
  • double:64 位双精度浮点数。
  • float:32 位单精度浮点数。
json
{
"mappings": {
"properties": {
"price": {
"type": "double"
},
"quantity": {
"type": "integer"
}
}
}
}

示例

  • 输入:{"price": 19.99, "quantity": 100}
  • 输出:price 存储为双精度浮点数,quantity 存储为整数。

1.3 日期类型(Date)

Elasticsearch 支持日期类型,可以存储日期和时间。日期类型支持多种格式,默认格式为 yyyy-MM-dd'T'HH:mm:ss.SSSZ

json
{
"mappings": {
"properties": {
"created_at": {
"type": "date"
}
}
}
}

示例

  • 输入:{"created_at": "2023-10-01T12:00:00Z"}
  • 输出:created_at 字段存储为日期类型。
警告

如果日期格式不匹配,Elasticsearch 会抛出解析错误。建议明确指定日期格式。

1.4 布尔类型(Boolean)

布尔类型用于存储 truefalse 值。

json
{
"mappings": {
"properties": {
"is_active": {
"type": "boolean"
}
}
}
}

示例

  • 输入:{"is_active": true}
  • 输出:is_active 字段存储为布尔值。

1.5 二进制类型(Binary)

二进制类型用于存储 Base64 编码的二进制数据。

json
{
"mappings": {
"properties": {
"file": {
"type": "binary"
}
}
}
}

示例

  • 输入:{"file": "U29tZSBiaW5hcnkgZGF0YQ=="}
  • 输出:file 字段存储为二进制数据。

2. 复杂数据类型

除了核心数据类型,Elasticsearch 还支持一些复杂数据类型,用于处理更复杂的数据结构。

2.1 对象类型(Object)

对象类型用于存储 JSON 对象。

json
{
"mappings": {
"properties": {
"user": {
"type": "object",
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "integer"
}
}
}
}
}
}

示例

  • 输入:{"user": {"name": "Alice", "age": 30}}
  • 输出:user 字段存储为一个对象,包含 nameage 子字段。

2.2 数组类型(Array)

Elasticsearch 支持数组类型,数组中的元素可以是任意数据类型,但所有元素必须是同一类型。

json
{
"mappings": {
"properties": {
"scores": {
"type": "integer"
}
}
}
}

示例

  • 输入:{"scores": [90, 85, 95]}
  • 输出:scores 字段存储为一个整数数组。
注意

数组中的元素必须为同一类型,否则会抛出错误。

2.3 嵌套类型(Nested)

嵌套类型用于存储对象数组,每个对象可以独立查询。

json
{
"mappings": {
"properties": {
"comments": {
"type": "nested",
"properties": {
"author": {
"type": "text"
},
"content": {
"type": "text"
}
}
}
}
}
}

示例

  • 输入:{"comments": [{"author": "Alice", "content": "Great post!"}, {"author": "Bob", "content": "Thanks!"}]}
  • 输出:comments 字段存储为一个嵌套对象数组。

3. 地理数据类型

Elasticsearch 支持地理数据类型,用于存储地理位置信息。

3.1 地理点类型(Geo-point)

地理点类型用于存储经纬度坐标。

json
{
"mappings": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}

示例

  • 输入:{"location": {"lat": 40.7128, "lon": -74.0060}}
  • 输出:location 字段存储为地理点。

3.2 地理形状类型(Geo-shape)

地理形状类型用于存储复杂的地理形状,如多边形、线等。

json
{
"mappings": {
"properties": {
"area": {
"type": "geo_shape"
}
}
}
}

示例

  • 输入:{"area": {"type": "polygon", "coordinates": [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]]]}}
  • 输出:area 字段存储为地理形状。

4. 实际案例

假设我们正在构建一个电商网站的搜索功能,需要存储商品信息。以下是一个示例映射:

json
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"price": {
"type": "double"
},
"tags": {
"type": "keyword"
},
"created_at": {
"type": "date"
},
"location": {
"type": "geo_point"
}
}
}
}

示例数据

json
{
"name": "无线蓝牙耳机",
"price": 99.99,
"tags": ["electronics", "audio"],
"created_at": "2023-10-01T12:00:00Z",
"location": {
"lat": 40.7128,
"lon": -74.0060
}
}

5. 总结

Elasticsearch 提供了丰富的数据类型,可以满足各种场景的需求。选择合适的数据类型不仅可以提高查询性能,还能确保数据的准确性。本文介绍了 Elasticsearch 的核心数据类型、复杂数据类型和地理数据类型,并通过实际案例展示了它们的应用。

6. 附加资源

7. 练习

  1. 创建一个索引,包含 textkeyworddategeo_point 类型的字段。
  2. 插入一些示例数据,并尝试查询这些数据。
  3. 修改映射,为同一个字段同时定义 textkeyword 类型,并测试其效果。