ElasticSearch 7.x with Springboot 2.3.x - 在Kibana中操作ES 万字长文

通过Kibana操作ES

为什么要用Kibana操作ES呢?

  1. 你会一直用代码去操作Oracle、MySQL、Mongo、Redis吗?
    不会,你会找一个工具来方便直接操作数据库,那么用Kibana操作ES就是这么一个工具;

  2. 在Kibana里快速了解与实践ES有哪些接口、分别能做什么,加深对其功能与数据结构的了解;

找到Kibana的ES操作面板

  • 在浏览器访问你的Kibana地址(我本机是 localhost:5601);
  • 在左侧导航菜单找到Dev Tools并点击;
  • 看到一个左右分栏的页面, 现在我们在左分页输入一个指令看看
    GET /_cat/health?v
    这是查看ES的健康状况,如果使用的是单节点,状态会始终是 yellow 不会是 green。想要绿还得多节点运动。

创建一个索引

直接插入一条数据来自动创建索引

  • 当插入一条数据时,如果ES原本没有这个index,系统默认会自动创建该索引,我们来试试:
PUT /customer/_doc/1
{
  "name": "乔尔",
  "des": "最后生还者的主角",
  "game": "The last of us"
}

你会得到下面的返回:

{
  "_index" : "customer",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 2,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}
  • 我们来查询一下该数据是否已存在:
GET customer/_doc/1

返回回来了:

{
  "_index" : "customer",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 2,
  "_seq_no" : 1,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "name" : "乔尔",
    "des" : "最后生还者的主角",
    "game" : "The last of us"
  }
}

是的,老乔尔在这里了,还没有被干掉,向乔尔敬个礼,最后生还者2的编剧夹带了太多私货,还有天理吗?还有王法吗?这样做你的良心不会痛吗?
不能像我一样做个不加带私货,就单纯讲讲技术~~(私货)~~ 的人吗。

在这里插入图片描述

  • 使用过旧版ES的老司机会纠结type,在ES7开始已经取消了type,_doc在API里也是一个关键字,类似效果的还有下面这个API:
//将_doc替换成了_create, 再次提交该请求时,会提示该document已存在
PUT /customer/_create/2
{
  "name": "艾莉",
  "des": "最后生还者的女主角",
  "game": "The last of us"
}

是不是很方便,不用像关系型数据库一样还要建表,直接插入数据就表也有了,数据也有了,有了这样的电动车还要啥自行车?

在这里插入图片描述
自行车还是要的,毕竟电动车还要电,没电的时候怎么办呢?难道用爱发电?不要骗自己了,程序员哪里有爱?所以我们一起来看看自行车吧。

正儿八经创建一个index

之前怎么就不正儿八经了?
在这里插入图片描述
ES的数据存入后,还记得前言中数据入库到建立索引的过程吗?一大精华就是如何将你的数据建立索引,如果你不告诉ES,他是不知道的,那么就只能自己匹配了,在简单的应用场景下没有什么问题,可是如果想把你的电动车玩成酷炫的改装痛车,那么就要为你的每个零件做定制,现在我们就先来看看如何为不同字段指定类型。

我们先删除刚才创建的index:

DELETE /customer

接下来我们重新建立索引 character:

PUT /character
{
    "settings" : {
        "number_of_shards" : 1
    },
    "mappings" : {
        "properties" : {
            "name" : { "type" : "keyword" },
            "des" : { "type" : "text" },
            "game" : { "type" : "text" },
            "age" : { "type" : "integer" }
        }
    }
}

上面的命令让我们建立了一个新的index -> character,其中的mappings下的properties,我们指定了字段的属性,我们将name的属性设为keyword,那么它将不会进行分词,而是整个被索引,这就和其他数据库的索引在效果上一样了。

ES有以下这些基本类型:

核心数据类型:
  • string
    text, keyword, wildcard
  • Numeric
    long, integer, short, byte, double, float, half_float, scaled_float
  • Date
    date
  • Date nanoseconds
    date_nanos
  • Boolean
    boolean
  • Binary
    binary
  • Range
    integer_range, float_range, long_range, double_range, date_range, ip_range
复合数据类型:
  • Object
    单个json类型
  • Nested
    一组嵌套的json类型
地理位置数据类型:
  • Geo-point
    geo_point 经纬度坐标点
  • Geo-shape
    geo_shape 一个多边形区域

对index干点别的吧

克隆索引

克隆的命令很简单,不过有一些注意事项,克隆只需要这样就可以:

// 将character克隆到character2
POST /character/_clone/character2

这里要注意一些前提条件

  1. 你的ES节点健康度必须是绿的,不绿不行;
  2. 将现有index变为只读,如何变为只读呢?
PUT /character/_settings
{
  "settings": {
    "index.blocks.write": true
  }
}

删除与关闭index

删除

当你想抹去某个index的存在时,就使用该命令,如果你的原始数据在别的库,ES仅仅作为一个索引库时,该操作影响相对有限,否则那就真的是从删库到跑路了:

DELETE /character

在这里插入图片描述

关闭

当你想要保留某个index又不想人读写它时,就用该命令:

POST /character/_close

查看index

如果已经建立了index,我们自然想要看看这个index到底存在不存在,到底长啥样,对吧。

我有多少index

在kibana中输入下面命令看看你刚才创建的index在吗?没有建或者已删库?

GET _cat/indices

在里面看到你的index了吗?

查看具体某个index

现在你想知道某个具体的index,看看他的properties,又几个副本,什么时候创建的,以及是否有特殊settings?这个命令也很简单:

GET character

你也可以用如下命令来判断某个index是否存在,如果存在会返回200,不存在则返回404。

HEAD character

是时候来点document了

自带ID的数据插入

我们在做数据插入时,可以为数据指定ID,这样系统在存入数据时ID就会是我们传入的值,我们来看看怎么做

//PUT /{index_name}/_doc/{id}
PUT /character/_doc/2
{
  "name": "艾莉",
  "des": "最后生还者的女主角",
  "game": "The last of us 2",
  "age": 16
}

这里的返回数据会告诉我们,数据的ID为2,那么我们如果不指定ID呢?不指定的时候会怎样呢?让我们来看看,老乔尔走起:

自动生成ID

//这里我们将请求方式改为了POST,因为这里一定是创建,URI最后没有ID
POST /character/_doc/
{
  "name" : "乔尔",
  "des" : "最后生还者的主角",
  "game" : "The last of us",
  "age": 46
}

我们来看看返回数据:

{
  "_index" : "character",
  "_type" : "_doc",
  "_id" : "Rpvl33IB_-zdUMCBv_pD",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}

ID是一串随机生成的字符串,当然我们可以修改ID的激活规则,自动生成ID的规则由settings中的action.auto_create_index控制:

// 这个命令表示character使用自动生成ID,以customer开头的关闭自动生成ID,以user开头的使用自增ID
PUT _cluster/settings
{
    "persistent": {
        "action.auto_create_index": "character,-customer*,+user*" 
    }
}

PUT _cluster/settings
{
    "persistent": {
        "action.auto_create_index": "false" 
    }
}

PUT _cluster/settings
{
    "persistent": {
        "action.auto_create_index": "true" 
    }
}

添加超时时间

ES的写入效率并不是特别高,在实际生产环境中,我们总要考虑网络IO的耗时以及其所带来的线程占用及可能的应用崩溃,而在微服务中不考虑这样的问题甚至可能造成系统的雪崩,所以我们希望系统能够快速失败,失败后我们可以重试也可以选择其他降级方案,ES也为我们提供了这样的能力,可以让我们快速失败:

//我们在URI后添加了timeout,如果3s还没响应则会返回我们超时
POST character/_doc?timeout=3s
{
  "name": "艾比",
  "des": "最后生还者2的反派,但是你却不得不操作她去杀主角,WTF。",
  "game": "The last of us 2",
  "age": 20
}

简单查询

看看这个index下的所有documents

我们有时候就想随便看看一个数据库表中的一些数据,我们对于数据的感觉常常要看到这些数据才会有,这时候我们要怎么做呢?

GET character/_search

不带任何参数,是不是很简单。

查看具体ID的数据

//Rpvl33IB_-zdUMCBv_pD : 乔尔的ID
//返回乔尔的document
GET character/_doc/Rpvl33IB_-zdUMCBv_pD
//判断乔尔是否存在
HEAD character/_doc/Rpvl33IB_-zdUMCBv_pD
//只返回乔尔的数据本身
GET character/_source/Rpvl33IB_-zdUMCBv_pD

只返回特定字段

这时我们只要在调用时添加要返回的source字段即可:

//我们只要知道乔尔的名字以及出自哪个游戏
GET character/_source/Rpvl33IB_-zdUMCBv_pD?_source=name,game

现在我们已经会根据ID查询了,虽然和想象的不太一样,因为我们想要的不应该是用ID来查询,我们想要根据关键字就找到数据。

不要急,我们要循序渐进让你找到感觉,这种感觉就是在轮环中前进,接下来让我们看看更高级的用于搜索的奇巧yinji(哎呀我这输入法怎么坏了打不出来了)
在这里插入图片描述
憋说话,开搞!

复杂搜索

特定属性值

我们想要找到乔尔,但是我们并不知道他的ID,我们只记住了他的名字,可怜的老乔尔,让我们试试找到他吧。

//我们之前用过这个_search,现在我们加上了一个新参数 -> q=name:乔尔
GET character/_search?q=name:乔尔&_source=name,game

我们找到乔尔了,但是这样是不是会感觉比较乱?那么我们来这样试试:

GET /character/_search
{
  "query": {
    "term": {
      "name": "乔尔"
    }
  }
}

以前有小伙伴质疑过这样的请求不是应该是POST吗? GET要跟在URI后面,其实不是这样的。

对返回数据做分页与排序

我们要找到所有描述中带“最”字的数据,然后根据年轻倒序排序,并返回前两个,我们来看看怎么做吧:

GET /character/_search
{
  "query": {
    "match": {
      "des": "最"
    }
  },
  "sort": [{"age": "desc"}], 
  "from": 0,
  "size": 2
}

复杂查询条件

上面我们的查询条件还是比较单一,要知道再SQL里面我们可以有各种 AND, OR, NOT 以及括号操作,在这里我们要怎么办呢?
我想要描述里带最的数据,同时年龄要大于16岁小于等于46岁的,怎么办呢?居然还有这么骚的操作?
在这里插入图片描述
那么我们来看看怎么在查询中满足要求:

GET /character/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "des": "最后"
          }
        }
      ],
      "filter": [
        {
          "range": {
            "age": {
              "gt": 16,
              "lte": 46
            }
          }
        }  
      ]
    }
  },
  "sort": [{"age": "desc"}], 
}
  • bool 关键字表示我们要进行组合查询;
  • must 表示里面的条件都要满足,类似于SQL的AND关键字;
  • should 表示其中的条件满足其一就可以,类似于SQL的OR;
  • must_not 表示不需要满足该条件,类似于SQL的NOT;
  • 这里我们使用了与 must 并列的 filter,这里面可以输入多个条件,它只是根据条件做数据过滤,不进行打分等操作,在性能上优于match的查询,因此如果我们需要快速缩小查询范围时,就可以用filter。

模糊搜索与同义词搜索

模糊搜索

当我们在query中使用 match 时,他默认已经支持了模糊搜索,这里的模糊搜索与我们在关系型数据库中的含义不太一样,在关系型数据库里表示我们要使用 LIKE 了,但是在ES里,表示我们输错了一两个字,它依然帮我们把数据找出来。
让我们试试下面的搜索条件:

GET /character/_search
{
  "query": {
    "match": {
      "des": "最后生活者"
    }
  }
}

我们的数据依然返回了,但是大家看到几条数据的score值,都没有满分,因为我们有错别字。

同义词

该功能的使用需要对同义词做一些配置,这样我们就可以简化搜索,比如:
tlou = the last of us
这里我们不对这一块深入讲解了,因为其难点不在使用。

同一关键字在不同字段匹配

这个可以认为时对于 bool 操作的简化,我们来试一试:

GET /character/_search
{
  "query": {
    "multi_match": {
      "query": "最后生活者",
      "fields": ["game", "des"]
    }
  }
}

删除数据

到这里,已经很累了,感觉已经精疲力尽了,饭也没吃厕所也没上的写,我们终于要开始做数据删除了,这个篇章也就快要接近收尾了。
在这里插入图片描述

根据ID删除数据

这个语法比较简单,不过要注意不要一不小心删除了整个index

//删除ID为1的角色
DELETE /character/_doc/1

根据查询条件删除

我们来让艾比离开最后生还者的世界吧:

POST character/_delete_by_query
{
  "query": {
    "match": {
      "name": "艾比"
    }
  }
}

这样艾比就不见了,我们用_search去找时,再也找不到她了,TLOU的世界清净了。
是不是似曾相识的语法? 如果你很好的掌握了上面的复杂查询,那么这里将没有任何难度。
BTW,如果艾比的形象和艾莉丝与蒂法差不多,我们还是可以让她留下来并且接受她成为主角。
在这里插入图片描述

更新数据

根据ID覆盖原数据

这个操作会根据id,覆盖原本的数据,不会只修改你提交的字段:

PUT /character/_doc/2
{
  "des": "最后生还者1和2的女主角,在2的表现让人失望",
  "age": 16
}

这样提交后,ID为2的数据,就没有name与game属性了,那么显然这不是我们想要的。

只修改有变动的自动

通常我们只想要修改要改变的字段,没有变动的字段保持原样,那么我们该怎么做呢?

POST /character/_update/2
{
  "doc": {
    "des": "最后生还者1和2的女主角,在2的表现让人失望",
    "age": 18
  }
}

这样提交后原本的name与game属性则不会发生变化。

根据查询条件进行数据修改

是的,现在我们并不知道数据的ID,我们想要找到艾莉,在我们写这段分享的漫长过程中,艾莉又长大了一岁,真是光阴似箭岁月如梭,艾莉已经19岁了,我们应该怎么办呢?

POST character/_update_by_query
{
  "script": {
    "source": "ctx._source['age'] = 19"
  },
  "query": {
    "match": {
      "name": "艾莉"
    }
  }
}

query的部分依然参考上面的复杂查询模块,script是一个新知识点,但是我们也不做展开了,我们只要理解 “source”: “ctx._source[‘age’] = 19” 是将查询到的数据的age字段改为19就可以了。

关于通过Kibana进行ES的CRUD操作,我们就介绍到这里了,不知不觉这已经是一篇万字长文了。

下一步,我们就要移步到通过 Springboot 与 Spring Data Elasticsearch 来使用ES了。想想还有些小激动,是不是。
在这里插入图片描述
基础知识还要补充的小伙伴请前往:
ElasticSearch 7.x with Springboot 2.3.x - 前言
ElasticSearch 7.x with Springboot 2.3.x - 基础准备

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Elasticsearch 简介 ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算,能够达到实时搜索,稳定,可靠,快速,安装使用方便。elasticSearch 的使用场景 1、在海量数据前提下,对数据进行检索。比如:京东,淘宝等电商项目课程目标: 1. 了解企业级搜索引擎2. 安装elasticsearch 课程目录: 01 课程介绍02 elasticsearch 简介03 elasticsearch 使用场景04 安装elasticsearch 之前先安装jdk05 安装elasticsearch06 测试elasticsearch是否安装成功 07 安装kibana08 elasticsearch 基本认识 以及添加索引和删除索引09 elasticsearch 添加查询数据10 elasticsearch 修改删除数据11 elasticsearch 有条件的查询12 分词子属性fuzzy查询13 elasticsearch 过滤使用14 elasticsearch 排序与分页15 elasticsearch 如何查询指定的段16 elasticsearch 高亮显示17 elasticsearch 聚合18 elasticsearch mapping 概念19 elasticsearch文词库20 elasticsearch 文词库安装测试21 elasticsearch 文词库的使用案例22 elasticsearch 自定义词库配置23 安装nginx 配置文词库24 测试elasticsearch 自定义文词库25 搭建项目父工程26 搭建项目bean-interface-common27 搭建search 的service web 项目28 测试项目是否能与elasticsearch联通29 创建数据库并搭建首页30 数据上传功能的实现类完成31 数据上传控制器完成32 dubbo 介绍以及安装zookeeper33 将数据从mysql 上传到elasticsearch 34 elasticsearch查询功能分析35 编写业务需求的dsl 语句36 编写输入参数返回结果集的实体类37 实现类编写38 编写实现类dsl 语句39 返回集结果转换40 结果测试41 测试通过输入查询条件并将数据显示到页面

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值