基于ES 7.7
包括4个api: Put mapping
, Get mapping
, Get field mapping
, Type exists
(7.0.0已废弃)
1. 设置/Put mapping
给已现有的索引添加字段, 或者修改现有字段的搜索设置(search settings)。官方文档
#设置单个索引
PUT /<index_name>/_mapping
# 同时设置多个索引(使用同样的mapping)
PUT /<index_name,index_name2>/_mapping
# 更新所有索引: 可以忽略索引名称, 或者使用参数 `_all`
PUT /_all/_mapping
PUT /_maping
查询参数
allow_no_indices
当没有匹配的索引时,是否正常返回数据(否则抛出错误)。
如果设置为true
, 则当使用通配符(*)、索引别名、_all
匹配到的索引不存在(missing)或者已关闭(closed)时,不会抛出错误。
默认false
, 表示会抛出错误。
expand_wildcards
通配符查询时可以匹配的索引的条件, 多个值之间以英文逗号分割, 比如"open,hidden"。默认是open
。可用的值有:
- all: 匹配所有open和closed的索引, 包括隐藏的(hidden).
- open: 默认, 表示只匹配开放中的索引
- closed: 只匹配关闭的(closed)的索引
- hidden: 匹配隐藏的(hidden)的索引, 必须和open/closed联合使用. (官方文档说open和closed可以一起用, WAF??)
- none: 不接受通配符.
ignore_unavailable
如果有索引不存在时是否忽略。
默认false
,就是返回404并抛出错误信息。查询时只要有一个索引不存在,则都抛出错误。
master_timeout
连接到master节点的超时时间,默认 30s
timeout
等待返回结果的超时时间,默认 30s
Request Body
*properties
必填, mapping对象。字段的mapping。
如果是一个新的字段,会包含以下映射:
- 字段名称
- 字段数据类型
- mapping的参数
如果是已存在的字段, 则参照本节内容后面的 "如果修改已存在字段的映射".
几个栗子
1. 新建索引时
单个索引:
# 单个索引
## 先建立一个索引, 不带mapping
PUT /publications
## 再定义索引的mapping
PUT /publications/_mapping
{
"properties": {
"title": { "type": "text"}
}
}
同时给多个索引定义一样的mapping:
# 先建立两个索引, 不带mapping
PUT /twitter-1
PUT /twitter-2
# 给这两个索引设置一样的mapping
PUT /twitter-1,twitter-2/_mapping
{
"properties": {
"user_name": {
"type": "text"
}
}
}
同时给多个索引设置mapping时, 可以使用通配符, 且遵循 多个索引名称规则(multiple index names)
2. 给已存在的object字段增加新的属性
我们可以使用"put mapping api"给已有的object类型的字段增加新的属性。
我们先新建一个索引,同时指定一个object类型的字段name
, 它内部有一个text
类型的字段first
。
DELETE /my_index
PUT /my_index
{
"mappings":{
"properties":{
"name":{
"properties": {
"first":{
"type": "text"
}
}
}
}
}
}
查看mapping, 这时name只有一个字段:
现在我们给这个object类型的字段name
添加一个内部的text类型的字段last
:
PUT /my_index/_mapping
{
"properties":{
"name":{
"properties":{
"last":{
"type": "text"
}
}
}
}
}
再次查看mapping定义, 会发现name多了一个字段last:
3. 给一个已有的字段增加 multi-fields
multi-fields 可以让你以不同的方式去索引一个字段,从而达到不同的搜索目的。
比如, 建立一个索引, 字段city
初始时是一个text
类型, 支持全文搜索。
DELETE /my_index
# 建立索引
PUT /my_index
{
"mappings":{
"properties":{
"city":{
"type": "text"
}
}
}
}
但是在进行 排序 或 聚合 时需要用到keyword
类型以提供更高的查询效率。现在我们来给city
字段添加一个keyword
类型的multi-filed字段raw
, 这样就可以提高该字段的排序(sorting)效率。
PUT /my_index/_mapping
{
"properties":{
"city":{
"type":"text",
"fields":{
"raw":{
"type":"keyword"
}
}
}
}
}
4. 更改已有字段支持的mapping参数
每个mapping参数的文档里有说明是否可以使用 put mapping api 对现有字段进行更新。例如,您可以使用 put mapping api 来更新ignore_above
参数。
例如, 我们创建一个索引, 含有一个keyword
类型的字段user_id
, 且这个字段有一个值为20
的参数ignore_above
:
DELETE /my_index
PUT /my_index
{
"mappings":{
"properties":{
"user_id":{
"type": "keyword",
"ignore_above": 20
}
}
}
}
P
现在我们要用api把这个ignore_above
参数的值修改为100
:
PUT /my_index/_mapping
{
"properties":{
"user_id":{
"type": "keyword",
"ignore_above": 100
}
}
}
5. 修改已有字段的mapping
不能直接修改mapping或已有字段的类型,否则会导致已经索引的数据失效。
如果需要更改字段的mapping, 请使用正确的mapping新建一个索引,然后reindex数据到新的索引。
如果尝试通过api变更字段的类型, ES会抛出错误.
栗子: 创建一个索引users
, 包含一个long类型的user_id字段, 然后写入2个文档:
PUT /users
{
"mappings":{
"properties":{
"user_id":{
"type": "long"
}
}
}
}
# 插入2个文档
POST /users/_doc/12345
{
"user_id": 12345
}
POST /users/_doc/12346
{
"user_id": 12346
}
如果我们直接修改字段的定义会怎么样? ES会拒绝!
So, 还是老老实实的重建一个索引,然后用reindex
来复制数据吧。
# 新建一个索引
PUT /users_new
{
"mappings":{
"properties":{
"user_id":{
"type": "keyword"
}
}
}
}
# 使用reindex复制数据(这个复制可以执行多次, ES会自动判断是需要create还是update)
POST /_reindex
{
"source":{
"index": "users"
},
"dest":{
"index": "users_new"
}
}
数据复制结果:
{
"took" : 65,
"timed_out" : false,
"total" : 2,
"updated" : 0,
"created" : 2,
"deleted" : 0,
"batches" : 1,
"version_conflicts" : 0,
"noops" : 0,
"retries" : {
"bulk" : 0,
"search" : 0
},
"throttled_millis" : 0,
"requests_per_second" : -1.0,
"throttled_until_millis" : 0,
"failures" : [ ]
}
这个
reindex
是用来同步一个索引的数据到另外一个索引, 会自动进行create/update/delete数据的操作.
6. 字段重命名( rename a field )
重命名字段会导致在旧的字段名称下已索引的数据无效,应该通过添加一个别名(alias)的方式来提供可替代的字段名。
栗子: 创建一个索引users, 包含一个字段user_id
, 然后我们给这个字段加一个别名uid
# 字段重命名
DELETE /users
# 下建立索引
PUT /users
{
"mappings":{
"properties":{
"user_id":{
"type": "keyword"
}
}
}
}
# 插入2个文档
POST /users/_doc/12345
{
"user_id": 12345
}
POST /users/_doc/12346
{
"user_id": 12346
}
# 给字段user_id加别名
PUT /users/_mapping
{
"properties":{
"uid":{
"type": "alias",
"path": "user_id"
}
}
}
添加别名后, 执行GET /users/_mapping
查看新的mapping:
{
"users" : {
"mappings" : {
"properties" : {
"uid" : {
"type" : "alias",
"path" : "user_id"
},
"user_id" : {
"type" : "keyword"
}
}
}
}
}
现在我们来查询一下uid=12345的:
# 查询
GET /users/_search?filter_path=hits.hits
{
"query": {
"match": {
"uid": 12345
}
}
}
是可以正常查询的, 结果如下:
返回的是原字段名称,那么如果返回别名呢? TODO
那么问题来了: 如何删除一个字段呢????? TODO
2. 获取/Get mapping
# 获取集群里所有索引的mapping
GET /_all/_mapping
GET /_mapping
# 获取指定索引的mapping, 可以指定索引名称或者别名
GET /<index_name_OR_index_alias>/_mappig
# 同时获取多个索引的maping, 多个索引之间以逗号分割
GET /index1,index2,index3/_mapping
ES 7.0.0版本开始弃用
type
, mapping定义中不再返回. 如果需要旧的格式, 可以使用参数 include_type_name=true
查询参数
allow_no_indices
当没有匹配的索引时,是否正常返回数据(否则抛出错误)。
如果设置为true
, 则当使用通配符(*)、索引别名、_all
匹配到的索引不存在(missing)或者已关闭(closed)时, 不会抛出错误。
默认false
, 表示会抛出错误。
expand_wildcards
通配符查询时可以匹配的索引的条件, 多个值之间以英文逗号分割, 比如"open,hidden"。默认open
。可用的值有:
- all: 匹配所有open和closed的索引, 包括隐藏的(hidden).
- open: 默认, 表示只匹配开放中的索引
- closed: 只匹配关闭的(closed)的索引
- hidden: 匹配隐藏的(hidden)的索引, 必须和open/closed联合使用. (官方文档说open和closed可以一起用, WAF??)
- none: 不接受通配符.
ignore_unavailable
如果有索引不存在时是否忽略。
默认false
,就是返回404并抛出错误信息。查询时只要有一个索引不存在,则都抛出错误。
官方文档说"If true, missing or closed indices are not included in the response." 这个与实测不同
local
是否仅从本地节点获取信息
默认false
,表示从master节点获取信息。
master_timeout
连接到master节点的超时时间,默认 30s
3. 获取指定字段的mapping ( Get field mapping)
获取一个或多个字段的mapping定义。如果你不需要完整的mapping或者索引的字段太多时会很有用。
GET /_mapping/field/<field>
GET /<index>/_mapping/field/<field>
路径参数
- field: 可选, 多个索引以英文逗号分割, 或者使用通配符表达式
- field: 可选, 多个字段以英文逗号分割
查询参数
- allow_no_indices
当没有匹配的索引时,是否正常返回数据(否则抛出错误)。
如果设置为true, 则当使用通配符(*)、索引别名、_all匹配到的索引不存在(missing)或者已关闭(closed)时,不会抛出错误。
默认true
, 表示不会抛出错误。
expand_wildcards
通配符查询时可以匹配的索引的条件, 多个值之间以英文逗号分割, 比如"open,hidden"。默认是open。可用的值有:
- all: 匹配所有open和closed的索引, 包括隐藏的(hidden).
- open: 默认, 表示只匹配开放中的索引
- closed: 只匹配关闭的(closed)的索引
- hidden: 匹配隐藏的(hidden)的索引, 必须和open/closed联合使用. (官方文档说open和closed可以一起用, WAF??) -- none: 不接受通配符.
ignore_unavailable
如果有索引不存在时是否忽略。这个官方文档原文描述("If true, missing or closed indices are not included in the response.")的不准确
默认false
,就是返回404并抛出错误信息。查询时只要有一个索引不存在,则都抛出错误。
include_defaults
返回的settings
中是否包含默认设置, 默认是 false
local
是否仅从本地节点获取信息。
默认false, 表示从master节点获取信息。
栗子
我们先建立一个包含object的索引:
PUT /publications
{
"mappings":{
"properties":{
"id":{"type": "text"},
"title":{"type": "text"},
"abstract":{"type": "text"},
"author":{
"properties":{
"id":{"type": "text"},
"name":{"type": "text"}
}
}
}
}
}
查看一个字段的定义
比如, 只查看title
字段的定义:
GET /publications/_mapping/field/title
返回数据如下:
{
"publications" : {
"mappings" : {
"title" : {
"full_name" : "title",
"mapping" : {
"title" : {
"type" : "text"
}
}
}
}
}
}
查看多个字段的定义
- 如果要查看多个字段的mapping定义,可以用英文的逗号分割。且会忽略不存在的字段。
GET /publications/_mapping/field/author.id,abstract,name
上面的代码查询3个字段,但是字段
name
是不存在的,正确的应该是author.name
,但是es是不会抛出错误的,仍然会返回有效的字段的信息。
执行结果:
# 忽略了不存在的字段 `name`, 只返回了 abstract 和 author.id
{
"publications" : {
"mappings" : {
"abstract" : {
"full_name" : "abstract",
"mapping" : {
"abstract" : {
"type" : "text"
}
}
},
"author.id" : {
"full_name" : "author.id",
"mapping" : {
"id" : {
"type" : "text"
}
}
}
}
}
}
- 可以使用通配符(*)
比如我们查询这个索引的所有以a
开头的字段的定义:
GET /publications/_mapping/field/a*
返回数据:
{
"publications" : {
"mappings" : {
"author.name" : {
"full_name" : "author.name",
"mapping" : {
"name" : {
"type" : "text"
}
}
},
"abstract" : {
"full_name" : "abstract",
"mapping" : {
"abstract" : {
"type" : "text"
}
}
},
"author.id" : {
"full_name" : "author.id",
"mapping" : {
"id" : {
"type" : "text"
}
}
}
}
}
}
返回的字段的顺序并不是按索引的mapping中定义的顺序来的。通常我们获取索引的完整的mapping时,字段是按照字母升序排列的。
查询多个索引的多个字段的定义
查询请求格式GET /<index>/_mapping/field/<field>
中的<index>
和<field>
支持逗号分割的多个名称,或通配符。如果要查询所有的索引, 可以用_all
来表示索引名称。
# 查询多个索引的一个字段
GET /twitter,users/_mapping/field/message
# 查询所有索引的多个字段
GET /_all/_mapping/field/message,user.id
# 查询所有索引的字段中内含id字段(那就是object类型了)
GET /_all/_mapping/field/*.id
注意: 使用_all
查询返回的结果和我们预想的不大一样:会返回所有的索引,但是每个索引的mapping中如果没有这个字段则显示空json。比如GET /_all/_mapping/field/message,user.id
返回的部分数据如下:
{
"users_new" : {
"mappings" : { }
},
".apm-custom-link" : {
"mappings" : { }
},
"kibana_sample_data_ecommerce" : {
"mappings" : { }
},
".kibana_task_manager_1" : {
"mappings" : { }
},
".apm-agent-configuration" : {
"mappings" : { }
},
"kibana_sample_data_logs" : {
"mappings" : {
"message" : {
"full_name" : "message",
"mapping" : {
"message" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
},...
}
4. 查询类型是否存在 (Type exists)
因ES 7.0.0废弃了
type
, 相应的Type exists
查询也废弃了
HEAD /<index>/_mapping/<type>
返回状态码:
指定的mapping类型存在返回200
, 只要有一个类型不存在就返回状态404
last updated at 2021/10/22 14:40