“ElasticSearch基础:数据类型和映射”的版本间差异
跳到导航
跳到搜索
(建立内容为“category:ElasticSearch == 关于 == <syntaxhighlight lang="java" highlight=""> </syntaxhighlight>”的新页面) |
小无编辑摘要 |
||
(未显示同一用户的1个中间版本) | |||
第1行: | 第1行: | ||
[[category: | [[category: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类型,这就不符合业务预期了。 | |||
== 自定义文档的数据类型 == | |||
语法: | |||
<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> |
2023年3月31日 (五) 21:51的最新版本
关于
映射(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" }
}
}
}
}
}