跳到主要内容

映射配置

映射(Mapping)定义了文档的结构,包括字段类型、分析器等配置。

映射类型

核心数据类型

类型说明示例
text全文搜索,会分词文章内容、标题
keyword精确匹配,不分词标签、状态、ID
integer32 位整数年龄、数量
long64 位整数ID、时间戳
float单精度浮点数价格
double双精度浮点数精确计算
boolean布尔值是否激活
date日期时间创建时间
binary二进制数据图片 Base64
range范围类型年龄范围

复杂数据类型

# 对象类型
PUT /articles
{
"mappings": {
"properties": {
"author": {
"properties": {
"name": { "type": "text" },
"email": { "type": "keyword" }
}
}
}
}
}

# 嵌套类型(数组中的对象独立索引)
PUT /articles
{
"mappings": {
"properties": {
"comments": {
"type": "nested",
"properties": {
"user": { "type": "keyword" },
"content": { "type": "text" }
}
}
}
}
}

text vs keyword

PUT /articles
{
"mappings": {
"properties": {
"title": {
"type": "text", # 全文搜索
"analyzer": "ik_max_word"
},
"status": {
"type": "keyword" # 精确匹配
},
"category": {
"type": "text", # 同时支持两种
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
}

# 查询时:
# 全文搜索:match { "category": "技术" }
# 精确匹配:term { "category.keyword": "技术" }

创建映射

创建索引时指定映射

PUT /articles
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"content": {
"type": "text",
"analyzer": "ik_max_word"
},
"author": {
"type": "keyword"
},
"category": {
"type": "keyword"
},
"views": {
"type": "integer"
},
"price": {
"type": "float"
},
"is_published": {
"type": "boolean"
},
"tags": {
"type": "keyword"
},
"created_at": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"location": {
"type": "geo_point"
}
}
}
}

动态映射

Elasticsearch 会自动推断字段类型:

# 插入文档时自动创建映射
POST /articles/_doc
{
"title": "测试文章", # 自动映射为 text
"views": 100, # 自动映射为 long
"is_active": true, # 自动映射为 boolean
"created_at": "2024-01-15" # 自动映射为 date
}

动态映射规则

JSON 类型Elasticsearch 类型
null不添加字段
booleanboolean
integerlong
floatfloat
stringtext + keyword
array取数组第一个元素的类型

关闭动态映射

PUT /articles
{
"mappings": {
"dynamic": false, # 忽略未知字段
"properties": {
"title": { "type": "text" }
}
}
}

# 或严格模式(遇到未知字段报错)
PUT /articles
{
"mappings": {
"dynamic": "strict",
"properties": {
"title": { "type": "text" }
}
}
}

更新映射

添加新字段

PUT /articles/_mapping
{
"properties": {
"summary": {
"type": "text"
},
"rating": {
"type": "float"
}
}
}

注意:已存在字段的类型不能修改,如需修改需要重建索引。

分析器

内置分析器

分析器说明
standard默认分析器,按空格分词
simple按非字母分词
whitespace按空格分词
stopstandard + 停用词过滤
keyword不分词,整体作为一个词
pattern使用正则表达式分词
language特定语言分析器

测试分析器

GET /_analyze
{
"analyzer": "standard",
"text": "Hello World, Elasticsearch!"
}

# 使用索引的分析器
GET /articles/_analyze
{
"field": "title",
"text": "测试分词效果"
}

自定义分析器

PUT /articles
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"my_stopwords"
]
}
},
"filter": {
"my_stopwords": {
"type": "stop",
"stopwords": ["的", "是", "在"]
}
}
}
},
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "my_analyzer"
}
}
}
}

字段属性

常用属性

PUT /articles
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart",
"boost": 2.0, # 权重
"index": true, # 是否索引(默认 true)
"store": false, # 是否单独存储
"norms": true, # 是否存储评分因子
"term_vector": "no" # 词向量存储
},
"content": {
"type": "text",
"index": false # 不索引,不能搜索
},
"views": {
"type": "integer",
"doc_values": true, # 用于排序和聚合
"index": false # 只用于排序聚合,不用于搜索
},
"internal_notes": {
"type": "text",
"index": false, # 不索引
"store": true # 单独存储
}
}
}
}

copy_to

将多个字段值复制到一个字段:

PUT /articles
{
"mappings": {
"properties": {
"title": {
"type": "text",
"copy_to": "full_content"
},
"content": {
"type": "text",
"copy_to": "full_content"
},
"full_content": {
"type": "text"
}
}
}
}

# 搜索时只需查询 full_content 字段
GET /articles/_search
{
"query": {
"match": {
"full_content": "搜索关键词"
}
}
}

小结

本章我们学习了:

  1. 核心数据类型和复杂数据类型
  2. text 和 keyword 的区别
  3. 动态映射
  4. 分析器配置
  5. 字段属性详解

练习

  1. 创建一个商品索引,定义合适的字段类型
  2. 配置一个自定义分析器
  3. 使用 copy_to 实现多字段搜索
  4. 测试不同分析器的分词效果

参考资源