本文以ES7.7版本为基础.
推荐一个他人在用的基于nodejs的web管理界面: elasticsearch-head , 我仍然在用kibana
查看所有index
GET /_cat/indices
indices 是index的复数形式.
查看索引的定义 mapping
先看下官方演示数据 flights data的结构:
GET /kibana_sample_data_flights/_mapping
执行结果:
{
"kibana_sample_data_flights" : {
"mappings" : {
"properties" : {
"AvgTicketPrice" : {
"type" : "float"
},
"Cancelled" : {
"type" : "boolean"
},
"Carrier" : {
"type" : "keyword"
},...
"DestLocation" : {
"type" : "geo_point"
},...
"DistanceMiles" : {
"type" : "float"
},
"FlightDelay" : {
"type" : "boolean"
},
"FlightDelayMin" : {
"type" : "integer"
},....
"FlightTimeHour" : {
"type" : "keyword"
},
"FlightTimeMin" : {
"type" : "float"
},
"Origin" : {
"type" : "keyword"
},
"OriginAirportID" : {
"type" : "keyword"
},...
"OriginCountry" : {
"type" : "keyword"
},
"OriginLocation" : {
"type" : "geo_point"
},
"OriginRegion" : {
"type" : "keyword"
},
"OriginWeather" : {
"type" : "keyword"
},
"dayOfWeek" : {
"type" : "integer"
},
"timestamp" : {
"type" : "date"
}
}
}
}
}
再看下我们之前定义的一个index:
GET twitter/_mapping
执行结果:
{
"twitter" : {
"mappings" : {
"properties" : {
"address" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"age" : {
"type" : "long"
},
"city" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"country" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"location" : {
"type" : "geo_point"
},
"message" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"province" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"uid" : {
"type" : "long"
},
"user" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
上面的命令mapping
就是我们今天要学习的mapping的一部分.
mapping
mapping是定义一个文档及其栏位(fields)的过程, 存储并被索引. 比如, 我们可以使用mapping去做这些事:
- 哪些字符串类型的栏位需要使用全文索引
- 哪些栏位包含数字(numbers), 日期(dates), 地里位置(geolocations)
- 定义日期类型值的格式
- 自定义规则, 以控制动态添加的栏位(dynamically added fields)
一个mapping定义包含:
- 元字段(Meta-fields)
元字段用于自定义如何处理文档的元数据, 比如: _index
, _id
, _source
- Fields or properties
mapping包含了一个文档的字段或属性的列表.
7.0版本之前, mappings 定义中还包含了一个type. 更多参考Removal of mapping types
参考官方文档
字段的数据类型
字段类型包含以下几种:
-
特殊类型: geo_point, geo_shape, completion
通常我们会以不同的方式索引同一个字段, 比如一个字符串类型的字段会被作为text
类型以用于分词后的全文索引, 也会被作为keyword
类型用于关键词全词匹配或聚合. 也可以使用标准分析器(standard analyzer)、英语分析器(english analyzer)和法语分析器(french analyzer)为字符串字段编制索引。
这就是multi-fields的用途, 大多数类型都可以通过fileds
参数来支持它.
防止mapping爆炸
栏位数量不要超过index.mapping.total_fields.limit
的设置值(默认是1000
), 以避免导致内存不足或者难以恢复(recover)的情况.
这个与mysql每个表栏位数量限制类似, 虽然mysql最多可以支持4096个栏位, 但是过多的栏位可能会导致一个16kb的page无法容纳至少2条数据, 从而不符合B-Tree的要求.
更多的参考官方文档.
明确定义mapping
虽然ES支持动态mapping(dynamic mapping, 自动把新的栏位名称添加到索引), 但是为了更精确的定义栏位类型, 还是建议给出明确的定义.
对于已经存在的index, 无法修改栏位类型(但是可以添加栏位), 只能删除index, 然后重新定义, 再导入数据
创建一个索引的mapping:
PUT /my-index
{
"mappings": {
"properties": {
"age": { "type": "integer" },
"email": { "type": "keyword" },
"name": { "type": "text" }
}
}
}
向一个mapping添加栏位:
PUT /my-index/_mapping
{
"properties": {
"employee_id": {
"type": "keyword",
"index": false
}
}
}
PUT /my-index/_mapping
{
"properties": {
"emp_no": {
"type": "keyword"
}
}
}
修改栏位
- 栏位类型修改: 不支持, 只能重建索引.
- 栏位更名: 建议使用
别名
alias
查看一个索引的mapping定义
GET my-index/_mapping
查看一个索引的mapping中的某一个栏位的定义:
GET my-index/_mapping/field/employee_id