Elasticsearch 字段多种类型处理
{ "mappings": { "properties": { "name": { "type": "text", // 主字段,用于全文搜索 "fields": { "keyword": { // 子字段名 "type": "keyword", // 子字段,用于精确匹配 "ignore_above": 256 } } } } } }
1.
◦
2.
◦
GET dev_companies/_search { "query": { "match": { "name": "Dragon Ball" } } }
- 精确匹配: 采用子字段
name.keyword
(类型为keyword
),用于匹配未分词的值:
GET dev_companies/_search { "query": { "term": { "name.keyword": "Dragon Ball Co., Ltd." } } }
- 短语应匹配: 如果需要匹配分词序列,使用
match_phrase
及远离参数slop
:
GET dev_companies/_search { "query": { "match_phrase": { "name": { "query": "Dragon Ball", "slop": 2 } } } }
时间字段应用场景
例如,在实际场景中,对时间字段也存在两种需求:
- 时间范围搜索:想搜索某个时间范围内的文档。
- 原始值保存:想保存原始的时间字符串,便于展示和精确搜索。
选择使用多字段
使用主字段
timestamp
完成时间范围搜索,使用子字段 timestamp.raw
完成原始值匹配。字段定义
{ "mappings": { "properties": { "timestamp": { "type": "date", "format": "strict_date_optional_time||epoch_millis", // 支持ISO8601和时间戳 "fields": { "raw": { "type": "keyword" // 子字段,用于保存原始时间字符串 } } } } } }
timestamp
主字段:- 类型为
date
,适用于时间范围查询(如range
查询)。 - 格式支持 ISO8601 格式(
strict_date_optional_time
)和 Unix 时间戳(epoch_millis
)。
timestamp.raw
子字段:- 类型为
keyword
,存储原始时间字符串,适合精确匹配(如term
查询)。
实现示例
- 时间范围搜索:
GET my_index/_search { "query": { "range": { "timestamp": { "gte": "2025-01-01T00:00:00Z", "lte": "2025-12-31T23:59:59Z" } } } }
- 精确匹配原始值:
GET my_index/_search { "query": { "term": { "timestamp.raw": "2025-01-06T12:00:00Z" } } }
多字段与多独立字段对比
多字段(Multi-fields)
-
优点:
- 数据一致性高,存储在同一个字段下,子字段只是不同的索引方式。
- 索引管理简单,只需要管理一个字段的映射。
-
存储空间优化,字段不会重复存储原始数据
-
缺点:
- 子字段的功能受限,不能自定义存储行为。
多独立字段
-
优点:
- 每个字段可以完全独立,支持不同的存储规则和查询方式。
- 灵活性更高,适合复杂场景(如支持多种时间格式)。
-
缺点:
- 数据冗余,占用更多存储空间。
- 索引管理复杂,查询时需要明确字段名称。
选择建议
-
如果需求涉及 不同字段的多种功能(如不同格式的时间存储和处理),建议使用 多独立字段。
如果需求主要集中在 同一字段的多种查询方式(如全文搜索和精确匹配),建议使用 多字段
每天逼着自己写点东西,终有一天会为自己的变化感动的。这是一个潜移默化的过程,每天坚持编编故事,自己不知不觉就会拥有故事人物的特质的。 Explicit is better than implicit.(清楚优于含糊)