ElasticSearch基础:数据类型和映射

来自Wikioe
跳到导航 跳到搜索


关于

映射(mapping)这个概念, 类似数据库中的表结构定义(schema),描述了文档包含哪些字段、每个字段的数据类型是什么。

数据基础类型

ES支持的数据类型:

  • 字符串
    主要包括: textkeyword 两种类型,keyword 代表精确值不会参与分词,text 类型的字符串会参与分词处理。
    • text 类型支持全文搜索,因为 text 涉及分词,所以可以配置使用什么分词器,尤其涉及中文分词。
  • 数值
    包括: long,integer,short,byte,double,float
  • 布尔值:boolean
  • 时间:date
  • 数组
    数组类型不需要专门定义,只要插入的字段值是 json 数组就行。
  • GEO类型
    主要涉及地理信息检索、多边形区域的表达。

精确值 & 全文类型

  1. 精确值:通常指的就是,数值类型、时间、布尔值、字符串的 keyword 类型,这些不可分割的数据类型,精确值搜索效率比较高,精确值匹配类似 MYSQL 中根据字段搜索。
    例如:拿一个手机号去搜索数据,对于每一个文档的手机号字段,要么相等,要么不等,不会做别的计算。
    • 用于精确搜索
  2. 全文类型:指的就是 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" }
      	}
      }
    }
  }
}