“ElasticSearch基础:数据类型和映射”的版本间差异

来自Wikioe
跳到导航 跳到搜索
(建立内容为“category:ElasticSearch == 关于 == <syntaxhighlight lang="java" highlight=""> </syntaxhighlight>”的新页面)
 
无编辑摘要
第2行: 第2行:


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


<syntaxhighlight lang="java" highlight="">
== 数据基础类型 ==
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类型,这就不符合业务预期了。
== 自定义文档的数据类型 ==
语法:
<syntaxhighlight lang="JSON" highlight="">
PUT /{索引名字}
{
  "mappings": { // 表示定义映射规则
      "properties": { // 定义属性,也就是字段类型
        "字段名1":    { "type": "字段类型" }, 
        "字段名2":    { "type": "字段类型" }
        ...(提示:最后一行末尾不要加逗号)...
      }
  }
}
</syntaxhighlight>
示例:创建一个订单索引,索引名字order
: 订单索引结构如下表:
:{| class="wikitable"
! 字段名 !! ES类型 !! 描述
|-
| id || integer || 订单id,整数
|-
| shop_id || integer || 店铺Id, 整数
|-
| user_id || integer || 用户id, 整数
|-
| order_no || keyword || 订单编号,字符串类型,精确值
|-
| create_at || date || 订单创建时间,日期类型
|-
| phone || keyword || 电话号码,字符串类型,精确值
|-
| address || text || 用户地址,字符串类型,需要'''模糊搜索'''
|}
: 创建ES索引:
: <syntaxhighlight lang="JSON" highlight="">
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"  }
      }
  }
}
</syntaxhighlight>
== 查询索引的映射规则 ==
如果想知道索引的映射规则(索引结构)是怎么样的,可以通过下面语法查询。
语法:
<syntaxhighlight lang="JSON" highlight="">
GET /索引名/_mapping
{
 
}
</syntaxhighlight>
示例:
<syntaxhighlight lang="JSON" highlight="">
GET /order/_mapping
{
}
</syntaxhighlight>
返回:
<syntaxhighlight lang="JSON" highlight="">
{
  "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"
        }
      }
    }
  }
}
</syntaxhighlight>
== JSON嵌套类型定义 ==
ES 的映射也支持 Object 类型,使用 JSON 嵌套类型定义。
示例:有以下json,其 user 属性是一个 Object 类型,json 类型本身支持这种通过对象无线嵌套的结构
<syntaxhighlight lang="JSON" highlight="">
{
"order_no" : "20200313120000123123",
"shop_id" : 12,
"user" : {
"id" : 100,
"nickname" : "dacui",
}
}
</syntaxhighlight>
嵌套 json 的定义如下:
<syntaxhighlight lang="JSON" highlight="">
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" }
      }
      }
    }
  }
}
</syntaxhighlight>
</syntaxhighlight>

2021年5月20日 (四) 21:15的版本


关于

映射(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" }
      	}
      }
    }
  }
}