映射操作
索引创建后,需要设置字段的约束信息,叫做字段映射(mapping)。字段的约束包括:字段的数据类型、是否要存储、是否要索引、分词器。
创建映射字段
语法:
PUT /索引名/_mapping
{
"properties": {
"字段名": {
"type": "数据类型",
"index": true,
"store": false,
"analyzer": "分词器"
}
}
}
示例:
PUT /wzkicu-index
PUT /wzkicu-index/_mapping/
{
"properties": {
"name": {
"type": "text",
"analyzer": "ik_max_word"
},
"job": {
"type": "text",
"analyzer": "ik_max_word"
},
"logo": {
"type": "keyword",
"index": "false"
},
"payment": {
"type": "float"
}
}
}
映射属性详解
-
type 类型:
- String类型:text 可分词,不可参与聚合。keyword 不可分词,作为完整字段进行分配,可以参与聚合
- Numerical类型:数值类型,分两类,基本数据类型、浮点数的高精度类型
- Date:日期类型,ES 可以对日期格式化字符串存储,但是建议存储为毫秒值、存储为 long,节省空间
- Array 数组类型:进行匹配时,任意一个元素满足,都认为满足
- Object 对象:
{ name: "jack", age: 21, girl: {name: "Rose", age: 21}},如果存储到索引库是对象类型,会把 girl 变成 girl.name 和 girl.age
-
index:true 字段会被索引,则可以用来进行搜索,默认值就是 true。false 字段不会被索引,不能用来搜索
-
store:是否将数据进行独立存储,原始的文本存储在 _source 里面,默认情况下其他提取出来的字段都不是独立存储的,是从 _source 里面提取出来的
-
analyzer:指定分词器,一般使用 IK 分词器 ik_max_word / ik_smart
查看映射关系
GET /索引名称/_mapping
GET _mapping
GET _all/_mapping
修改映射关系
主要注意的是:修改映射只能是增加字段的操作,其他的更改只能删除索引重新建立索引来实现。
一次性建立索引与映射
PUT /索引库名称
{
"settings":{
"索引库属性名":"索引库属性值"
},
"mappings":{
"properties":{
"字段名":{
"映射属性名":"映射属性值"
}
}
}
}
文档增删改查与局部更新
文档,即索引库中的数据,会根据规则创建索引,将用来搜索,可以类比做数据库中的一行数据。
新增文档
手动新增:
POST /索引名称/_doc/{id}
{
"name" : "百度",
"job" : "小度用户运营经理",
"payment" : "30000",
"logo" : "https://profile-avatar.csdnimg.cn/xxx.jpg"
}
自动新增:
POST /索引名称/_doc
{
"field": "value"
}
查询文档
单个文档:
GET /索引名称/_doc/{id}
所有文档:
POST /索引名称/_search
{
"query":{
"match_all": {}
}
}
定制返回字段:
GET /索引名称/_doc/1?_source=name,job
更新文档
全部更新:
PUT /索引名称/_doc/{id}
{
"name" : "百度",
"job" : "百度测试",
"payment" : "20000",
"logo" : "https://xxx.jpg"
}
局部更新:
POST /索引名/_update/{id}
{
"doc":{
"field":"value"
}
}
注意:ES 执行更新操作的时候,ES 是先将旧的标记为删除,再添加新的文档。
删除文档
ID删除:
DELETE /索引名/_doc/{id}
条件删除:
POST /索引名/_delete_by_query
{
"query": {
"match": {
"字段名": "搜索关键字"
}
}
}
删除所有:
POST /索引名/_delete_by_query
{
"query": {
"match_all": {}
}
}
错误速查
| 症状 | 根因定位 | 修复 |
|---|---|---|
| PUT 索引/_mapping 报错:mapper_parsing_exception | 已存在字段类型与本次提交的 type / analyzer 不兼容 | 查看索引当前 _mapping,比对字段类型与新配置 |
| 修改已有字段类型后,旧数据查询行为”怪异” | 映射没真正变(老 segment 仍按旧映射) | 坚持”映射设计好再建索引”,需要调整时走”新索引 + reindex”方案 |
| 查询命中数为 0,但确认数据在 _source 中存在 | 字段 index:false 或被映射为 keyword,而查询使用了分词匹配 | 需要全文检索就用 text + analyzer;只做精确匹配用 keyword |
| keyword 字段做模糊搜索 / 中文搜索效果极差 | keyword 不分词,只存整值;中文必须配合分词器使用 text 类型 | 常用模式:text + keyword 多字段 |
| POST 索引/_update/id 报版本冲突 | 误把”局部更新”和”全量覆盖”混用;或高并发下版本冲突 | 局部更新统一用 _update + doc;高并发场景考虑乐观锁或重试策略 |
| 使用 DELETE_BY_QUERY 删除后,磁盘空间短期内几乎没变化 | ES 先”标记删除”,等待 segment merge 才真正回收空间 | 属于正常行为,等待后台合并;空间压力大时考虑 force merge |
| 查询 _source 返回字段过大,接口延迟与网络开销明显 | 默认返回完整 _source,包含所有字段 | 使用 ?_source=字段1,字段2 限制返回字段 |
| 全量更新 PUT 后发现”新增了一条数据” | 之前该 id 不存在,ES 将其视为新文档创建 | 确认业务语义:需要”仅当存在才更新”时,需先 GET 或使用脚本更新条件 |