年终了,清理一下自己的OneNote,把笔记迁移到博客上来。
什么是映射
数据库建表的时候,我们DDL依据一般都会指定每个字段的存储类型,例如:varchar、int、datetime等,目的很明确,就是更精确的存储数据,防止数据类型格式混乱,在Elasticsearch中也是这样,创建爱你索引的时候一般也需要指定索引的字段类型,这种方式称为映射(Mapping)。
字段类型
映射针对的是文档的字段,数据库中有varchar、int、datetime等数据类型,那么ElasticSearch中又有哪些字段类型,每个字段类型都代表什么意思呢?
Elasticsearch支持文档字段有多种不同的数据类型,根据官方文档分类,可以划分以下几个类别:核心数据类型、复杂数据类型、Geo(地址)数据类型、专用数据类型和多字段。
核心数据类型
- 字符串类型:主要包括text和keyword
- 数字类型:主要包括long、integer、short、byte、double、float、half_float、scaled_float
- 日期类型
- 布尔类型
- 二进制类型
- 范围数据类型:integer_range、float_range、long_range、double_range、date_range
多字段
有时候单纯的一个字段类型满足不了我们复杂的需求,为了不同的目的,以不同的方式索引同一个字段通常很有。多字段也是ES的一种数据类型,只不过结合了更多的功能。
例如,对于字符串字段,我们既可以将他映射为text类型用于全文搜索,亦可以将它映射为keyword类型用于排序或聚合,或者,还可以使用标准分词器、英语分词器和其他语言分词器索引文本字段。
大多数数据类型都通过fields参数支持多字段。例如对于城市名称的多字段映射,可以这样写:
PUT my_index
{
"mappings": {
"_doc": {
"properties": {
"cityName": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
}
}
}
}
}
映射
映射是定义一个文档及其包含的字段如何存储和索引的过程。例如,使用映射来定义:
- 应将那些字符串字段视为全文字段;
- 那些字段包含数字,日期或地理文字;
- 是否应将文档中所有字段的值索引到catch-all_all字段中;
- 日期值的格式;
- 自定义规则以控制动态添加字段的映射。
其实在ElasticSearch中可以不需要实现定义映射(Mapping),文档写入Elasticsearch是,会根据文档字段自动识别类型,但是通过这种自动识别的字段不是很精确,对于一些复杂的需要分词的就不合适了。
根据是否自动识别映射类型,我们可以将映射分为动态映射和静态映射。
- 动态映射
即不实现指定映射类型(Mapping)、文档写入Elasticsearch是,ES会根据文档自动识别类型,这种机制称为动态映射。
比如:
PUT /library/book/1
{
"bookId":1,
"bookName":"Java核心技术 卷I",
"publishDate":"2014-03-12"
}
我们可以通过 GET /library/_mapping 的到映射信息:
{
"library": {
"mappings": {
"book": {
"properties": {
"bookId": {
"type": "long"
},
"bookName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"publishDate": {
"type": "date"
}
}
}
}
}
}
可以看到我们没有创建索引是,Elasticsearch自动根据文档为我们映射了字段类型,bookid的映射类型为long、bookName的映射为多字段类型:text和keyword,publishDate的映射类型为date,可以看到ES的动态映射功能还是很强大的。
默认情况下,当文档中找到以前未见到过的字段,Elasticsearch会自动将这个新字段添加到类型映射中。我们可以在文档和object级别禁用这项功能,具体操作方式就是通过dynamic参数这只为false或strict,设置为false是忽略新字段,而设置为strict是如果遇到未知字段,就抛出异常。
- 静态映射
即认为实现定义好映射,包含文档的多个字段及其类型等,这种方式称为静态映射,亦可称为显式映射。
静态映射的自动类型推测功能并不是100%正确的,这就需要静态映射机制。静态映射与数据库中创建表语句类型,需要实现指定字段类型。相对于动态映射,静态类型可以添加更加详细字段类型、更精准的配置信息等。