一、前言
上一篇文章中,我们学习了如何使用Java客户端去连接并且简单的操作ES,今天我们将对ES中的基本操作进行学习,包括索引操作、映射操作、文档操作。
二、索引操作
简单回顾一下索引,ES中的索引就有相同结构的数据的集合,对应到关系型数据库例如Mysql中就是表。接下来我们学习索引的基本操作。
1、创建索引
语法:
PUT /索引名
{
"settings":{
....
},
"mappings":{
"properties":{
"field1": { "type": "类型" },
"field2": { "type": "类型2" }
...
}
},
"aliases": {
....
}
}
settings:表示对当前索引设置一些属性,包括但不限于 分片数量、副本分片数。
mappings:表示映射,即A字段是什么类型,B字段是什么类型。
aliases:别名,可以给索引设置别名。
例如我们要创建一个酒店(hotel)索引,副本数为1,分片数为1(因为目前是单机),有3个字段 id、name、price。
PUT /hotel
{
"settings": {
"number_of_replicas": 1,
"number_of_shards": 1
},
"mappings": {
"properties": {
"id":{
"type": "long"
},
"name":{
"type": "text"
},
"price":{
"type": "double"
}
}
}
}
类似于Mysql中的
CREATE TABLE hotel (
id BIGINT PRIMARY KEY,
name VARCHAR(255),
price DOUBLE
) ENGINE=InnoDB;
2、删除索引
DLETE /{索引名}
删除索引,没太多可以说的就是把索引删除掉,类似Mysql中的Drop Table
3、关闭索引
在某些场景下,某个索引暂时不使用了,但时候后期可能又会使用,比如归档了,此时可以把当前索引关闭,被关闭的索引将不能写入和搜索,只能通过ES特定的API或者监控工具能看到索引的元数据信息。
语法:POST /索引名/_close
例如:POST /hotel/_close
4、打开索引
有关闭索引那么一定就有开启索引,也很好理解就是把关闭的索引重新打开,让他可以继续写入和搜索。
语法:POST /索引名/_open
例如:POST/索引名/_open
5、索引别名
顾名思义就是给索引设置一个别名,是索引别名和索引之间建立某种逻辑关系。Mysql中也有别名,例如在使用JOIN的时候我们通常会使用别名(select t1.id,t2.name from table t1 left join on table t2 on t1.id = t2.id)
这里列举一个ES中别名的使用场景,例如我们建立了3个索引,分别代表hotel(酒店)1,2,3月份的入住情况,假设此时是4月了,我们想查询1~3月的数据,则需要分别查询1月的索引、2月的索引、3月的索引这样代码整体就不优雅了,所以我们可以给这个3个索引设置相同的别名,例如就叫 last_three_month,那么在应用层只要直接对last_three_month 进行搜索即可,这里也就是我们说的建立了逻辑上的关联,如下图
语法
POST _aliases
{
"actions": [
{
"add": {
"index": "索引名",
"alias": "别名"
}
},
{
"add": {
"index": "索引名2",
"alias": "别名"
}
}
]
}
(详细的API:https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-aliases.html)
如果一个别名关联了多个索引,查询是没问题的,写入则不行,因为ES无法确定你究竟要向那个索引写入,所以写入的时候还是要指定对应索引名。
.
三、映射操作
映射:Mapping,指的是字段和类型的关系,就好比MySQL中的表。接下来我们学习如何操作索引
1、查询索引
语法:GET /索引名/_mapping
案例:GET /hotel/_mapping
结果:
{
"hotel" : {
"mappings" : {
"properties" : {
"city" : {
"type" : "keyword"
},
"price" : {
"type" : "double"
},
"title" : {
"type" : "text",
"analyzer" : "ik_max_word"
}
}
}
}
}
2、修改索引
在我们开发的过程中可能会涉及到对索引的修改,很遗憾ES不能修改映射中的字段类型,所以说修改可能不是很准确说是扩展索引,比如可以增加一个字段。
语法
PUT /索引名/_mapping
{
"properties":{
"字段":{
"type":"类型"
}
}
}
例如:
#给hotel索引新增description字段,类型为text,使用ik_max_word分词器
PUT /hotel/_mapping
{
"properties":{
"description":{
"type":"text",
"analyzer": "ik_max_word"
}
}
}
此时我们再次查看索引
GET /hotel/_mapping
结果
{
"hotel" : {
"mappings" : {
"properties" : {
"city" : {
"type" : "keyword"
},
"description" : {
"type" : "text",
"analyzer" : "ik_max_word"
},
"price" : {
"type" : "double"
},
"title" : {
"type" : "text",
"analyzer" : "ik_max_word"
}
}
}
}
}
3、基本数据类型
既然提到了索引,不得不提的就是ES中的基本数据类型,下面我们详细的说一下ES中的基本数据类型
3.1、keyword类型
keyword,关键词类型,该类型不参与分词(什么是分词这个会放到后续学习原理的时候再学习),简单的来说keyword类型的内容不会被切分,会当成完整的内容直接构建倒排索引(倒排索引是ES之所以这么快的原因之一,之后的学习也会学到)keyword一般用于对文档进行过滤,排序和聚合,例如我们通常会把“姓名”、“产品类型”这些不需要切分,或者说切分没有意义的字段设置为keyword类型。keyword只用于全词匹配来搜索。
案例:先写入
POST /hotel/_doc
{
"city":"杭州",
"description":"你好啊,这里是杭州如家酒店",
"price":200,
"title":"杭州如家酒店"
}
查询city字段
#查询案例1:
GET /hotel/_search
{
"query": {
"match": {
"city": "杭"
}
}
}
结果1:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
}
#查询案例2:
GET /hotel/_search
{
"query": {
"term": {
"city": {
"value": "杭州"
}
}
}
}
结果2:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "hotel",
"_type" : "_doc",
"_id" : "_OFHP5MBAePmk6wB4nHX",
"_score" : 0.2876821,
"_source" : {
"city" : "杭州",
"description" : "你好啊,这里是杭州如家酒店",
"price" : 200,
"title" : "杭州如家酒店"
}
}
]
}
}
3.2、Text类型
Text文本类型,和keyword不同,Text类型会被分词,在写入数据的时候ES会使用指定(或者默认)的分词器对Text类型的字段内容进行分词,例如的内容是 “杭州如家酒店”,可能会被分为 “杭州”、“如家”、“酒店”这几个词,然后根据这几个词去构建倒排索引。案例:
案例1
GET /hotel/_search
{
"query": {
"match": {
"description": "如家"
}
}
}
结果1:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.58446556,
"hits" : [
{
"_index" : "hotel",
"_type" : "_doc",
"_id" : "__OFHP5MBAePmk6wB4nHX",
"_score" : 0.58446556,
"_source" : {
"city" : "杭州",
"description" : "你好啊,这里是杭州如家酒店",
"price" : 200,
"title" : "杭州如家酒店"
}
}
]
}
}
GET /hotel/_search
{
"query": {
"match": {
"description": "这里"
}
}
}
#结果2:同上不在赘述
3.3、数值类型
ES中支持的数值类型包括,long、integer、short、byte、double、float、hafl_float、scaled_floadt和unsigned_long,具体的数值范围可以参考官网(https://www.elastic.co/guide/en/elasticsearch/reference/current/number.html),可以结合实际业务使用最合适的类型,这里不多赘述
3.4、布尔类型
布尔类型,用boolean定义用于表示是否,true或者false,这个相对简单。
3.5、日期类型
在ES中用date来表示日期类型,ES存储的日期是标准的UTC格式。一般使用如下的形式表示日期类型数据
- 格式化的日期字符串
- 毫秒级的时间戳
- 秒级时间戳
案例:
PUT /hotel
{
"mappings": {
"properties": {
"title":{
"type": "text",
"analyzer": "ik_max_word"
},
"city":{
"type": "keyword"
},
"price":{
"type": "double"
},
"create_time":{
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
}
}
}
}
4、复杂数据类型
受限于篇幅,这部分内容放在下一篇文章中继续
四、总结
今天的文章详细讲述了索引和映射的操作,同时也介绍了ES中的基本数据类型,下一篇文章讲继续讲解ES中的复杂数据类型,以及对文档的操作,希望对你有所帮助。