ElasticSearch基础:数据类型和映射
跳到导航
跳到搜索
关于
映射(mapping)这个概念, 类似数据库中的表结构定义(schema),描述了文档包含哪些字段、每个字段的数据类型是什么。
数据基础类型
ES支持的数据类型:
- 字符串:
- 主要包括: text 和 keyword 两种类型,keyword 代表精确值不会参与分词,text 类型的字符串会参与分词处理。
- text 类型支持全文搜索,因为 text 涉及分词,所以可以配置使用什么分词器,尤其涉及中文分词。
- 数值:
- 包括: long,integer,short,byte,double,float
- 布尔值:boolean
- 时间:date
- 数组
- 数组类型不需要专门定义,只要插入的字段值是 json 数组就行。
- GEO类型
- 主要涉及地理信息检索、多边形区域的表达。
精确值 & 全文类型
- 精确值:通常指的就是,数值类型、时间、布尔值、字符串的 keyword 类型,这些不可分割的数据类型,精确值搜索效率比较高,精确值匹配类似 MYSQL 中根据字段搜索。
- 例如:拿一个手机号去搜索数据,对于每一个文档的手机号字段,要么相等,要么不等,不会做别的计算。
- 用于精确搜索。
- 全文类型:指的就是 text 类型,会涉及分词处理,存储到 ES 中的数据不是原始数据,是一个个关键词。
- 例如:我们有一个title字段,数据类型是text, 我们插入"上海复旦大学"这个字符串,经过分词处理,可能变成:"上海"、"复旦大学"、"大学" 这些关键词,然后根据这些关键词建倒排索引。
- 用于模糊搜索。
实际项目中,如果不需要模糊搜索的字符类型,可以选择 keyword 类型,例如:手机号、email、微信的openid等等,如果选 text 类型,可能会出现搜出一大堆相似的数据,而且不是精确的数据。
自动映射
自动映射(dynamic mapping):没有预先定义文档的映射(数据类型),也可以插入数据,因为 ES 默认会自动检测我们插入的数据的类型,相当于自动定义文档类型(mapping)。
- 缺点:ES 映射的数据类型不一定是想要的类型。
- 例如:手机号,希望是一个精确值,使用keyword类型,ES 映射成为了text类型,这就不符合业务预期了。
自定义文档的数据类型
语法:
PUT /{索引名字}
{
"mappings": { // 表示定义映射规则
"properties": { // 定义属性,也就是字段类型
"字段名1": { "type": "字段类型" },
"字段名2": { "type": "字段类型" }
...(提示:最后一行末尾不要加逗号)...
}
}
}
示例:创建一个订单索引,索引名字order
- 订单索引结构如下表:
字段名 ES类型 描述 id integer 订单id,整数 shop_id integer 店铺Id, 整数 user_id integer 用户id, 整数 order_no keyword 订单编号,字符串类型,精确值 create_at date 订单创建时间,日期类型 phone keyword 电话号码,字符串类型,精确值 address text 用户地址,字符串类型,需要模糊搜索
- 创建ES索引:
PUT /order { "mappings": { "properties": { "id": { "type": "integer" }, "shop_id": { "type": "integer" }, "user_id": { "type": "integer" }, "order_no": { "type": "keyword" }, "create_at": { "type": "date", "format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"}, "phone": { "type": "keyword" }, "address": { "type": "text" } } } }
查询索引的映射规则
如果想知道索引的映射规则(索引结构)是怎么样的,可以通过下面语法查询。
语法:
GET /索引名/_mapping
{
}
示例:
GET /order/_mapping
{
}
返回:
{
"order" : {
"mappings" : {
"properties" : {
"address" : {
"type" : "text"
},
"create_at" : {
"type" : "date",
"format" : "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"id" : {
"type" : "integer"
},
"order_no" : {
"type" : "keyword"
},
"phone" : {
"type" : "keyword"
},
"shop_id" : {
"type" : "integer"
},
"user_id" : {
"type" : "integer"
}
}
}
}
}
JSON嵌套类型定义
ES 的映射也支持 Object 类型,使用 JSON 嵌套类型定义。
示例:有以下json,其 user 属性是一个 Object 类型,json 类型本身支持这种通过对象无线嵌套的结构
{
"order_no" : "20200313120000123123",
"shop_id" : 12,
"user" : {
"id" : 100,
"nickname" : "dacui",
}
}
嵌套 json 的定义如下:
PUT /order_v2
{
"mappings": {
"properties": { // 第一层json属性定义
"order_no": { "type": "keyword" },
"shop_id": { "type": "integer" },
"user": { // user属性是Object类型,可以单独定义属性类型
"properties" : { // 第二层user对象的属性定义
"id": { "type": "integer" },
"nickname": { "type": "text" }
}
}
}
}
}