ElasticSearch-初级
- (一)、什么是ElasticSearch(库、表、记录)
- 1.ElasticSearch是什么
- 2.ElasticSearch学习路线
- 3.聊聊Doug Cutting
- 4.Lucene 和 ElasticSearch的关系:
- (二)、ElasticSearch概述
- 1.基本概述
- 2.百度搜索关键字思考
- 3.目前都有哪些公司在用ElasticSearch技术
- (三)、ES和solr的差别
- 1.ElasticSearch 简介
- 2.Slor 简介
- 3.ES与Slor的区别
- (四)、ElasticSearch安装与搭建
- 1.安装的基本要求
- 2.下载与安装
- 3.window下安装
- 4.安装可视化界面 (elasticSearch Head)
- (1).解压ElasticSearch Head插件
- (2).安装Elasticsearch head插件
- (3).解决跨域问题-在ElasticSearch文件夹中
- (五).Kibana安装与搭建
- 1.什么是ELK
- 2.什么是Kibana
- 3.安装Kibanna
- (1).解压文件夹
- (2).启动Kibana
- (3).访问测试Kibana
- (4).汉化Kibana
- (六)、ES 核心概念
- 1.ElasticSearch概述
- 2.ElasticSearch是面向文档的
- 3.ElasticSearch 物理设计
- (1).一个elasticSearch就是一个集群
- (2).节点和分片如何工作
- (3).倒排索引
- 5.ElasticSearch 逻辑设计
- (1).文档 (行)
- (2).类型 (表)
- (3).索引 (库)
- (4).索引的列子
- (七)、IK分词器
- 1.什么是IK分词器
- 2.解压与安装IK分词器
- (1).解压并放置ElasticSearch目录中
- (2).重启ElasticSearch服务
- 3.Kibana进行测试
- (1).ik_max_word查看 (最大拆分)
- (2).ik_ik_smart查看 (最小拆分)
- (3).发现问题
- 4.自定义Ik分词器字典内容
- (1).新建 .dic文件
- (2).配置自定义dic
- (3).重启ElasticSearch文件
- (八)、Rest风格说明
- 1.什么是Rest风格
- 2.基础测试
- (1).创建一个索引 (PUT 需要指定文档id)
- (2).获取具体的索引 (GET 需要指定具体的索引)
- (3).第一种修改 (PUT 直接覆盖之)
- (4).第二种修改 (POST 这里文档后面要加_update)
- (5).删除索引 (DELETE 具体的索引或者文档)
- (九)、关于文档的基本操作 (重点)
- 1.基本操作
- (1). 添加操作 (PUT)
- (2).获取操作 (GET)
- (3).更新数据 (PUT)
- (4).更新数据 (POST _update) 推荐
- (5).简单的条件查询 (模糊查询)
- 2.复杂操作 (排序、分页、高亮、模糊查询、标准查询)
- (1).介绍基本的ElasticSearch的 JSON框架
- (2). 结果过滤 (_source)
- (3).排序 (sort)
- (4).分页查询 (form、size)
- (5).布尔值查询 - and (must)
- (6).布尔值查询 - or (should)
- (7).布尔值查询 - not (must_not)
- (8).布尔值查询 range- (filter)
- (9).多条件查询 (用空格隔开)
- (10).单个值的精确查询 (keyword+term)
- (11).多个值匹配精确查询
- (12).高亮查询
- (十)、集成SpringBoot
- 1.ElasticSearch依赖
- 2.初始化ElasticSearch
- 3.分析这个类的方法
- (1).创建一个空项目
- (2).在空项目中创建SpringBOOT模块
- (3).配置JDK版本
- 4.配置基本的项目
- (1).解决版本不一致问题
- (2).配置配置类文件
- 5.基本的索引 API操作 ⭐
- (1).创建索引
- (2).获取-删除 索引
- 6.基本的文档API操作 ⭐
- (1).新增文档
- (2).查看文档 (是否存在)
- (3).查看文档 (数据)
- (4).修改文档
- (5).删除文档
- (6).批量(添加/删除/修改)文档
- (7). 查询 ⭐⭐⭐⭐
- 7.全部的代码
注意保存以下文件的时候编码格式一定要是UTF-8,否则会报错。
(一)、什么是ElasticSearch(库、表、记录)
只要学不死、就往死里学
1.ElasticSearch是什么
就好比如我们去百度搜索吉士先生.发现百度给我们罗列出来了所有的列表数据。在没有ElasticeSearch技术之前,我们需要使用的是SQL语句的Like特殊关键字,现在我们只需要使用ElasticeSearch技术即可。
在大数据的情况下我们使用模糊查询会效率变得会非常的慢。
ElasticSearch: 搜索!(百度、CSDN、淘宝、电商)。
2.ElasticSearch学习路线
- ElasticSearch背景
- 货比三家 (slor、search、loosens)
- 搭建与安装ElasticSearch
- 生态圈
- 分词器(ik)
- RestFul操作ElasticSearch
- CRUD
前期我们可以把
ElasticSearch看作成一个数据库
,ElasricSearch数据库中有索引
、文档
、文档记录
。对应的是:库、表、记录
- SpringBoot集成ElasticSearch
- 爬虫爬取数据!
- 模拟全文检索
学完之后,只要用到搜索我们就可以使用ElasticSearch技术。建议在大数据的情况下使用ElasticSearch技术
3.聊聊Doug Cutting
1998年9月4日,Google公司在美国成立。正如大家所知道的那样,它是一家做 搜索
引擎起家的公司。
随着大数据时代的来临,许多互联网公司面临着搜索引擎的问题。
2003年谷歌发表(Google File System)谷歌文件系统。这是谷歌共公司为了存储海量数据
而设计的专用文件系统,2004年Doug Cutting实现了分布式文件存储系统 Nutch。
2004年谷歌发表了(MapReduce编程模型),这个模型用于大规模数据集(1TB)的并行分析运算(搜索引擎)
。2005年,Dog Cutting又基于MapReduce,在Nutch搜索引擎实现了该功能
。
生存法则: 不断地学习(虚心学习)、雅虎经验、优胜劣汰。
Lucence 是一套信息检索工具包 、jar包、不包含搜索引擎系统。包含的是:
索引结构、读写索引的工具、排序功能、搜索规则 ... 工具类
。
4.Lucene 和 ElasticSearch的关系:
ElasticSearch 是基于Lucence
做了一些封装和增强(我们上手是十分简单的)
(二)、ElasticSearch概述
1.基本概述
ElasticSearch(简称es)是一个基于Lucene的搜索服务器
。它提供了一个分布式多用户能力的全文搜索引擎,可以几乎实现实时的存储、检索数据
;本身扩展性很好可以扩展到上百台服务器上,处理PB级别(大数据时代)
的数据。基于restful API
接口。ElasticSearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎
。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装
使用方便。构建在全文检索开源软件Lucene之上的ElasticSearch,不仅能对海量规模的数据完成分布式检索与检索,还能提供数据聚合分析
。
2.百度搜索关键字思考
目前百度也正在使用ElasticSearch技术,为什么百度能够全文检索
、关键字高亮
、搜索推荐(搜索结果排序-权重)
。
3.目前都有哪些公司在用ElasticSearch技术
- 维基百科、类似于百度百科
- The Guardan(国内新闻网站)、类似于搜狐新闻
- Stack Overflow(国外的程序异常讨论论坛)
- 日志数据分析,ELK技术:
elasticsearch+logstash+kibana
- 商品价格监控网站: 当商品低于某个价格的时候通知用户
- 电商(淘宝、京东)
(三)、ES和solr的差别
1.ElasticSearch 简介
ES是一个实时分布式搜索和分析引擎。它让你以前所未有的速度处理大数据成为可能。
它主要用于全文搜索
、结构搜索
、分析
以及将这三者混合使用。
Elasticsearch是一个基于Apache Lucene™的开源搜索引擎。无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进性能最好的、功能最全的搜索引擎库
。
但是,Lucene只是一个库。想要使用它,你必须使用ava来作为开发语言并将其直接集成到你的应用中,更糕的是,Lucene非常复杂,你需要深入了解检索的相关知识来理解它是如何工作的。
ES也是有Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的式通过简单的RestFul APi来隐藏Lucene的复杂性,从而让全文搜索变得更加简单
。
2.Slor 简介
Sor 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器
。Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展,并对索引、搜索性能
进行了优化
Solr可以独立运行
,运行在etty、Tomcat等这些Servlet容器中,Solr 索的实现方法很简单,用 POST 方法向 Solr 服务器发送一个描述 Field 及其内容的 XML 文档,Solr根据xm文档添加、删除、更新索引
。Solr 搜索只需要发送 HTTP GET 请求,然后对 Sol返Xml、json等格式的查询结果进行解析,组织页面布局。Sor不提供构建UI的功能,Sor提供了一个管理界面,通过管理界面可以查询Solr的配置和运行情况
。
solr是基于lucene开发企业级搜索服务器,实际上就是封装了lucene。
Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口。用户可以通过http请求,向搜索引擎服务器提交一定格式的文件,生成索引;也可以通过提出查找请求,并得到返回结果。
3.ES与Slor的区别
背景:它们都是基于Lucene搜索服务器基础之上开发,一款优秀的,高性能的企业级搜索服务器。【是因为他们都是基于分词技术构建的倒排索引的方式进行查询】
开发语言:Java语言开发
诞生时间:Solr :2004年诞生。ES:2010年诞生。ES 更新【功能越强大】
区别:
-
当实时建立索引的时候,solr会产生io阻塞,而es则不会,
es查询性能要高于solr
。 -
在
不断动态添加数据
的时候,solr的检索效率会变的低下,而es则没有什么变化。 -
Solr利用zookeeper进行分布式管理,而
es自身带有分布式系统管理功能(免部署)
。Solr一般都要部署到web服务器上,比如tomcat。启动tomcat的时候需要配置tomcat与solr的关联。【Solr 的本质 是一个动态web项目】 -
Solr支持更多的格式数据[xml,json,csv等],而
es仅支持json文件格式
。 -
Solr是传统搜索应用的有力解决方案,但是es更适用于新兴的实时搜索应用。
单纯的对已有数据进行检索的时候,solr效率更好,高于es
。 -
Solr官网提供的功能更多,而es本身更注重于核心功能,高级功能多由第三方插件。
(四)、ElasticSearch安装与搭建
1.安装的基本要求
ES安装及head插件安装
声明:JDK 1.8以上,最低要求
!ElasticSearch 客户端。界面工具!
Java 开发,ElasticSearch的版本和我们之后对应的Java的核心jar包!版本对应
!JDK环境是正常!
2.下载与安装
官网:https://www.elastic.co/cn/elasticsearch/
我们要下载7.6.2版本
具有四个文件
ELK三件客,解压即用‘ 我用的都是 7.6.1的版本
3.window下安装
- 解压目录生成如下目录
bin 启动文件
config 配置文件
log4j2 日志配置文件
jvm,options java 虚拟机配置
elasticsearch.yml elasticsearch配置文件默认端口: 9200
lib 相关jar包
modules 功能模块
plugins 插件!ik 分词器
jvm.options 配置文件查看默认运行内存
C:\Environment\elasticsearch-7.6.2-windows-x86_64\elasticsearch-7.6.2\config
elasticsearch.yml 默认端口
2. 启动
点击 elasticsearch.bat
3. 访问 localhost:9200
4.安装可视化界面 (elasticSearch Head)
下载地址: https://github.com/mobz/elasticsearch-head
这个插件依赖于node.js环境还有npm环境。(Vue中已经搭配)
(1).解压ElasticSearch Head插件
(2).安装Elasticsearch head插件
1. cmd 命令安装
2. 开始安装
cnpm install
window下查看某一个端口号的PID: 最后我们发现是罗技鼠标占用了我们的9100
netstat -ntlp | findler 9100
修改默认的启动端口为9101
启动项目
npm run start
访问9101端口
(3).解决跨域问题-在ElasticSearch文件夹中
9101端口与9200端口是两个不同的端口需要跨域解决
1. 配置ElasticSearch配置文件
C:\Environment\elasticsearch-7.6.2-windows-x86_64\elasticsearch-7.6.2\config
2. 在elasticsearch.yaml文件中添加
http.cors.enabled: true http.cors.allow-origin: "*"
4. 重新启动ElasticSearch服务
5.如果遇到闪退的情况那么就是配置文件写错了
我们需要在冒号后面添加空格且换行
访问9101网址,访问成功
6.初学,就把es当作一个数据库!(可以建立索引(库),文档(库中的数据)) ·这个header我们就把它当做数据展示工具!我们后面所有的查询,Kibana来做·这个es head我们就把他当作数据展示工具!不建议在这里写SQL
(五).Kibana安装与搭建
1.什么是ELK
ELK是 Elasticsearch
,Logstash
,Kibana
三大开源框架首字母大写简称。市面上也被称为Elastic Stack
。其中ElasticSearch 是一个基于Lucene,分布式,通过Restful 方式进行交互的近实时搜索平台框架
。像类似百度,谷歌这种大数据全文搜索引擎的场景都可以使用Elasticsearch作为底层支持框架,可见Elasticsearch提供的搜索能力确实强大,市面上很多时候我们简称Elasticsearch为es。Logstash是ELK的中央数据流引擎,用于从不同目标(文件/数据存储/MQ)收集的不同格式数据,经过过滤后支持输出到不同目的地(文件/MQ/redis/elasticsearch/kafka等)
。Kibana可以将elasticsearch的数据通过友好的页面展示出来,提供实时分析的功能。
收集清洗数据–>搜素,存储–>kibana
市面上很多开发只要提到ELK能够一致说出它是一个日志分析架构技术栈总称,但实际上ELK不仅仅适用于日志分析,它还可以支持其他任何数据分析和收集的场景,日志分析和收集只是更具有代表性。并非唯一性。
2.什么是Kibana
Kibana是一个开源的分析与可视化平台,设计出来用于和Elasticsearch一起使用的。你可以用kibana搜索、查看存放在Elasticsearch中的数据
。Kibana与Elasticsearch的交互方式是各种不同的图表、表格、地图
等,直观的展示数据,从而达到高级的数据分析与可视化的目的。
Elasticsearch、Logstash和Kibana这三个技术就是我们常说的ELK技术栈,可以说这三个技术的组合是大数据领域中一个很巧妙的设计。一种很典型的MVC思想,模型持久层,视图层和控制层。Logstash担任控制层的角色
,负责搜集和过滤数据。Elasticsearch担任数据持久层的角色
,负责储存数据。而我们这章的主题Kibana担任视图层角色
,拥有各种维度的查询和分析,并使用图形化的界面展示存放在Elasticsearch中的数据。
3.安装Kibanna
注意:kibana 版本要和Es 一致
官网->查看kb与es版本的对应关系
(1).解压文件夹
解压文件夹,需要的时间比较长大概2分钟左右。
(2).启动Kibana
1.这里也许要Node.js的环境
2.开启Libana
Kibana需要依赖于ElasticSearch,ELasticSearch需要开启
3. 默认访问端口是 5601
(3).访问测试Kibana
1.访问测试
2.开发工具台
(4).汉化Kibana
- 查看汉化包
C:\Environment\kibana-7.6.1-windows-x86_64\kibana-7.6.1-windows-x86_64\x-pack\plugins\translations\translations
2. 配置汉化包
C:\Environment\kibana-7.6.1-windows-x86_64\kibana-7.6.1-windows-x86_64\config
3. 配置文件
4. 重启Kibana服务
(六)、ES 核心概念
1.ElasticSearch概述
我们已经掌握了es是什么,同时也把es的服务已经安装启动,那么es是如何去存储数据,数据结构是什么,又是如何实现搜索的呢?
集群,节点,索引,类型,文档,分片,映射是什么?
详细讲解: https://www.cnblogs.com/progor/p/11548269.html
2.ElasticSearch是面向文档的
elasticsearch 是面向文档,关系性数据库
和elasticsearch
客观对比!一切都是JSON
elasticsearch(集群)中可以包含多个索引(数据库),每个索引中可以包含多个类型(表),每个类型下又包含多个文档(行),每个文档中又包含多个字段(列)
3.ElasticSearch 物理设计
(1).一个elasticSearch就是一个集群
elasticearch 在后台把每个索引划分成多个分片
,每分分片可以在集群中的不同服务器间迁移
一个人就是一个集群!默认的集群名称就是 elasticsearch
(2).节点和分片如何工作
默认分片书就是五个:
一个集群至少有一个节点,而一个节点就是一个ealsticsearch进程
,节点可以有多个索引默认的,如果你创建索引,那么索引将会有5个分片(primary shard,又称主分片)构成的,每一个主分片会有一个副本(replica shard,又称复制分片)
上图一个有3个节点的集群,可以看到主分片和对应复制分片都不会在同一个节点内,这样有利于某个节点挂掉了,数据也不至于丢失。实际上,一个分片是一个lucene索引
,一个包含倒排索引的文件目录,倒排索引的结构使得elasticsearch在不扫描全部文档的情况下;就能告诉你哪些文档包含特定的关键字。不过,等等,倒排索引是什么鬼?
(3).倒排索引
elasticsearch使用的是一种称为倒排索引的结构,采用Lucenne倒排索引作为底层。这种结构适用于快速的全文搜索,一个索引由文档中所有不重复的列表构成,对于每一个词,都有一个包含它的文档列表。
例如,现在有两个文档,每个文档包含如下内容:
Study every day,good good up to forever # 文档1包含的内容
to forever,study every day,good good up # 文档2包含的内容
为了创建倒排索引,我们首先要将每个文档拆分成独立的词(或称为词条或者tokens),然后创建一个包含所有不重复的词条的排序列表,列出每个词条出现哪个文档:
现在,我们试图搜索to forever,只需要查看包含每个词条的文档。然后我们发发现图1的权重更高,因为他的 匹配度是2,百度的排序思想也是这样的,谁的权重高谁拍上面
5.ElasticSearch 逻辑设计
一个索引类型中,包含多个文档,比如说文档1,文档2。当我们索引一篇文档时,可以通过这样的一个顺序找到它:所以索引->类型->文档ID,通过这个组合我们就能索引到某个具体的文档。
注意:ID不必是整数,实际上它是个字符串
(1).文档 (行)
就是一条条数据在MySQL中就是一行行数据
user 表 : 1号用户张三18岁...
1 zhangsan 18
2 kuangshen 3
之前说elasticsearch是面向文档的,那么就意味着索引和搜索数据的最小单位是文档,elasticsearch中,文档有几个重要属性:
- 自我包含,一篇文档同时包含字段和对应的值,也就是同时包含
key:value
- 可以是层次型的,一个文档中包含自文档,复杂的逻辑实体就是这么来的!(就是一个
json对象!fastjson进行自动转换
!) - 灵活的结构,文档不依赖预先定义的模式,我们知道关系型数据库中,要提前定义字段才能使用,在elasticsearch中,对于字段是非常灵活的,有时候,我们可以忽略该字段,或者动态的添加一个新的字段
尽管我们可以随意的新增或者忽略某个字段,但是,每个字段的类型非常重要,比如一个年龄字段类型,可以是字符串也可以是整形。因为elasticsearch会保存字段和类型之间的映射及其他的设置。这种映射具体到每个映射的每种类型,这也是为什么在elasticsearch中,类型有时候也成为映射类型。
(2).类型 (表)
类型是文档的逻辑容器,就像关系型数据库一样,表是行的容器。类型中对于字段的定义称为映射,比如name映射为字符串类型。我们说文档是无模式的,它们不需要拥有映射中所定义的所有字段,比如新增一个字段,那某elasticsearch是怎么做的呢?elasticsearch 会自动的将新字段加入映射,但是这个字段的不确定它是什么类型,elasticsearch就开始猜,如果这个值是18,那么elasticsearch会认为它是整形。但是elatsicsearch也可能猜不对,所以最安全的方式就是提前定义好所需要的映射,这点跟关系型数据库殊途同归,先定义好字段,然后再使用,别整什么幺蛾子。
(3).索引 (库)
就是数据库。索引是映射类型的容器,elasticsearch中的索引是一个非常大的文档集合。索引存储了映射类型的字段和其他设置。然后它们被存储到了各个分片上了,我们来研究下分片是如何工作的。
(4).索引的列子
两个文档都匹配,但是第一个文档比第二个匹配程度更高。如果没有别的条件,现在,这两个包含关键字的文档都将返回。
再来看一个示例,比如我们通过博客标签来搜索博客文章。那么倒排索引列表就是这样的一个结构:
倒排索引:根据value找到ID ->(根据关键字找索引
)
如果要搜索含有python标签的文章,那相对于查找所哟原始数据而言,查找倒排索引后的数据将会快的多。只需要查看标签这一栏,然后获取相关的文章ID即可
。完全过滤掉无关的所有数据,提高效率!
elasticsearch的索引和Lucene的索引对比
在elasticsearch中,索引
(库)这个词被频繁使用,这就是术语的使用。在elasticsearch中,索引被分为多个分片,每份分片是一个Lucene的索引
。所以 一个elasticsearch索引是由多个Lucene索引。别问为什么,谁让elasticsearch使用Lucene作为底层呢!如无特指,说起索引都是指elasticsearch的索引。
接下来的一切操作都在kibana中Dev Tools下的Console里完成。基础操作!
(七)、IK分词器
下载地址: ik-7.6.2版本下载
1.什么是IK分词器
分词: 即把一段中文或者别的划分成一个个的关键字,我们咋在搜索时候会把自己的信息进行分成,会把数据库中或者索引库中进行分词,然后进行一个匹配的操作,默认的中文分词就是将每个字看成一个词,比如"我爱李明"会被分为"我",“爱”,“李”,“明”,这显然是不符合要求的,所以我们需要安装中文分词器IK来解决这个问题。
Ik提供了两个分词算法:
- ik_smart: 为最少切分。
- ik_max_word: 为最细粒度划分。
2.解压与安装IK分词器
(1).解压并放置ElasticSearch目录中
C:\Environment\elasticsearch-7.6.2-windows-x86_64\elasticsearch-7.6.2\plugins
(2).重启ElasticSearch服务
版本号要完全一致
elasticsearch-plugin list
3.Kibana进行测试
默认会有一个字典词库
(1).ik_max_word查看 (最大拆分)
GET _analyze
{
"analyzer": "ik_max_word",
"text": "中国人民"
}
(2).ik_ik_smart查看 (最小拆分)
GET _analyze
{
"analyzer": "ik_smart",
"text": "中国人民"
}
(3).发现问题
我们发现我们想不拆分的名词给我们拆分开来了。
对于我们自己需要自定义的词,需要我们自己加到分词器的字典里面。
4.自定义Ik分词器字典内容
C:\Environment\elasticsearch-7.6.2-windows-x86_64\elasticsearch-7.6.2\plugins\elasticsearch-analysis-ik-7.6.2\config
(1).新建 .dic文件
填充词汇
(2).配置自定义dic
如果建立多个自定义文件: 我们只需要复制一行值配置语句
<entry key="ext_dict">jsxs.dic</entry>
(3).重启ElasticSearch文件
(八)、Rest风格说明
1.什么是Rest风格
一种软件架构风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端
和服务器
交互类的软件。基于这个风格设计的软件可以更简洁
,更有层次
,更易于实现缓存
等机制。
1. 创建文档 PUT
2.
2.基础测试
(1).创建一个索引 (PUT 需要指定文档id)
- 创建索引名和文档 (不指定字段的类型)
PUT /索引名/类型名/文档id
{
请求体
}
PUT /test1/type1/1
{
"name":"吉士先生",
"age":3
}
打开:es-head查看我们创建的索引
查看索引的信息
- name 这个字段需不需要指定类型!
- 字符串类型
text keyword
不可分割 - 数值类型
long
integer
short
byte
double
float
half_float
scaled_float
- 日期类型
date
- 布尔值类型
boolean
- 二进制类型
binary
fs
等等…
- 创建索引名和文档 (指定字段的类型)
PUT /test2
{
"mappings": {
"properties": {
"name":{
"type": "text"
},
"age":{
"type": "long"
},
"birthday":{
"type": "date"
}
}
}
}
(2).获取具体的索引 (GET 需要指定具体的索引)
- 获取索引的的信息
GET test2
- 查看默认信息
PUT /test3/_doc/1
{
"name":"jsxs",
"age":13,
"brith":"2001-12-17"
}
1. 首先我们线创建一个索引
2. 查看默认信息
GET test3
如果我们自己的文档字段没有指定,那么es就会给我们默认配置字段类型!
扩展: 提供命令elasticsearch索引情况!通过GET _cat/indices 可以获得es当前很多信息
GET _cat/indices?v
(3).第一种修改 (PUT 直接覆盖之)
- 第一种:进行修改的操作 (曾经!!)
PUT /test3/_doc/1
{
"name":"jsxs11",
"age":13,
"brith":"2001-12-17"
}
(4).第二种修改 (POST 这里文档后面要加_update)
旧的 (PUT方法进行修改的操作)
PUT /test3/_doc/1
{
"name":"jsxs11",
"age":13,
"brith":"2001-12-17"
}
----------------------------
新的(POST方法进行修改的操作) 后缀加_update
POST /test3/_doc/1/_update
{
"doc":{ 在这里写修改的值
"name":"jsxs22"
}
}
(5).删除索引 (DELETE 具体的索引或者文档)
通过DELETE命令删除,根据你的请求来判断是删除索引还是删除文档记录!
# 删除指定索引
DELETE test1
# 删除某一个索引的指定文档
DELETE test3/_doc/1
(九)、关于文档的基本操作 (重点)
1.基本操作
(1). 添加操作 (PUT)
创建第一个数据
PUT /jsxs/user/1
{
"name":"吉士先生",
"age":22,
"desc":"一顿操作猛如虎,一看工资2500",
"tags":["技术宅","温暖的人","直男"]
}
创建第二个数据
PUT /jsxs/user/2
{
"name":"吉士先生2",
"age":23,
"desc":"一顿操作猛如虎,一看工资2600",
"tags":["技术宅2","温暖的人2","直男2"]
}
创建第三个数据
PUT /jsxs/user/3
{
"name":"吉士先生3",
"age":23,
"desc":"一顿操作猛如虎,一看工资2700",
"tags":["技术宅3","温暖的人3","直男3"]
}
(2).获取操作 (GET)
GET jsxs/user/1
(3).更新数据 (PUT)
PUT /jsxs/user/3
{
"name":"吉士先生4", #这里进行了修改
"age":23,
"desc":"一顿操作猛如虎,一看工资2700",
"tags":["技术宅3","温暖的人3","直男3"]
}
(4).更新数据 (POST _update) 推荐
这个可以选择性修改,而另一个会全部修改
POST /jsxs/user/3/_update
{
"doc":{
"name":"吉士先生55"
}
}
(5).简单的条件查询 (模糊查询)
GET /jsxs/user/_search?q=name:吉士先生2
2.复杂操作 (排序、分页、高亮、模糊查询、标准查询)
(1).介绍基本的ElasticSearch的 JSON框架
GET /jsxs/user/_search
{
"query": {
"match": {
"name": "吉士先生2"
}
}
}
kibana 里查询的参数体使用Json结构
eq ——> equal 代表相等
在JAVA里面 hit 是一个对象: 会得到所有的信息包括权重。
"hits" : [
{
"_index" : "jsxs",
"_type" : "user",
"_id" : "2",
"_score" : 3.8132527,
"_source" : {
"name" : "吉士先生2",
"age" : 23,
"desc" : "一顿操作猛如虎,一看工资2600",
"tags" : [
"技术宅2",
"温暖的人2",
"直男2"
]
}
},
{
"_index" : "jsxs",
"_type" : "user",
"_id" : "1",
"_score" : 2.577336,
"_source" : {
"name" : "吉士先生",
"age" : 22,
"desc" : "一顿操作猛如虎,一看工资2500",
"tags" : [
"技术宅",
"温暖的人",
"直男"
]
}
},
{
"_index" : "jsxs",
"_type" : "user",
"_id" : "3",
"_score" : 2.3163397,
"_source" : {
"name" : "吉士先生55",
"age" : 23,
"desc" : "一顿操作猛如虎,一看工资2700",
"tags" : [
"技术宅3",
"温暖的人3",
"直男3"
]
}
}
]
(2). 结果过滤 (_source)
有时候我们并不想要全部的数据都被打印出来,只需要打印出来部分即可,这时候我们就需要使用过滤了。默认的是全部打印出来...
只需要 name和desc
"_source":["name","desc"]
GET /jsxs/user/_search
{
"query": {
"match": {
"name": "吉士先生2"
}
},
"_source":["name","desc"]
}
(3).排序 (sort)
通过哪一个字段进行排序
根据年龄进行降序排序->desc asc->降序
"sort": [
{
"age": {
"order": "desc"
}
}
]
GET /jsxs/user/_search
{
"query": {
"match": {
"name": "吉士先生2"
}
},
"sort": [
{
"age": {
"order": "desc"
}
}
]
}
(4).分页查询 (form、size)
分页查询的操作....
从第0页即1页开始,然后每页展示2个数据
"from": 0,
"size": 2
GET /jsxs/user/_search
{
"query": {
"match": {
"name": "吉士先生2"
}
},
"sort": [
{
"age": {
"order": "desc"
}
}
],
"from": 0,
"size": 2
}
数据下标还是从0开始的。
(5).布尔值查询 - and (must)
must (and),所有的条件都要符合 where id=1 and name='xxx'
GET /jsxs/user/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "吉士先生2"
}
},
{
"match": {
"age": "23"
}
}
]
}
}
}
(6).布尔值查询 - or (should)
shold (or),所有的条件都要符合 where id=1 orname='xxx' or
GET /jsxs/user/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"name": "吉士先生2"
}
},
{
"match": {
"age": "23"
}
}
]
}
}
}
#! Deprecation: [types removal] Specifying types in search requests is deprecated.
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 3.9415374,
"hits" : [
{
"_index" : "jsxs",
"_type" : "user",
"_id" : "2",
"_score" : 3.9415374,
"_source" : {
"name" : "吉士先生2",
"age" : 23,
"desc" : "一顿操作猛如虎,一看工资2600",
"tags" : [
"技术宅2",
"温暖的人2",
"直男2"
]
}
},
{
"_index" : "jsxs",
"_type" : "user",
"_id" : "3",
"_score" : 2.5716512,
"_source" : {
"name" : "吉士先生55",
"age" : 23,
"desc" : "一顿操作猛如虎,一看工资2700",
"tags" : [
"技术宅3",
"温暖的人3",
"直男3"
]
}
},
{
"_index" : "jsxs",
"_type" : "user",
"_id" : "1",
"_score" : 1.7364457,
"_source" : {
"name" : "吉士先生",
"age" : 22,
"desc" : "一顿操作猛如虎,一看工资2500",
"tags" : [
"技术宅",
"温暖的人",
"直男"
]
}
}
]
}
}
(7).布尔值查询 - not (must_not)
即 年龄不等于23岁的...
GET /jsxs/user/_search
{
"query": {
"bool": {
"must_not": [
{
"match": {
"age": "23"
}
}
]
}
}
}
(8).布尔值查询 range- (filter)
范围值: gte即大于等于 。lte即小于等于
GET /jsxs/user/_search
{
"query": {
"bool": {
"must_not": [
{
"match": {
"name": "吉士先生2"
}
}
],
"filter": {
"range": {
"age": {
"gt": 8
}
}
}
}
}
}
(9).多条件查询 (用空格隔开)
这里只能对同一个字段进行用空格隔开查询,也就是数组。
GET /jsxs/user/_search
{
"query": {
"match": {
"tags": "男 技术2"
}
}
}
(10).单个值的精确查询 (keyword+term)
term
查询时直接通过倒排索引指定的词条进行精确
的查找。
- 关于分词:
-
term
,直接查询精确的。 -
match
,会使用分词器解析!(先分析文档,然后再通过分析的文档进行查询)
- 两个类型
- text: 不会被分词器进行解析。
- keyword: 会被分词器解析。
1. 创建索引库
PUT testdb
{
"mappings": {
"properties": {
"name":{
"type": "text"
},
"desc":{
"type": "keyword"
}
}
}
}
2.
插入两条数据
PUT testdb/_doc/2
{
"name":"狂神说Java name1",
"desc":"狂神说Java desc1"
}
3. keyword 查询不会被分词器解析
GET _analyze
{
"analyzer": "keyword",
"text": "狂神说Java name1"
}
4. text会被分词器给解析,standard默认就是text
GET _analyze
{
"analyzer": "standard",
"text": "狂神说Java name1"
}
- 精确查找
keyword+term才能精确查找,否则不会精确查找.
GET testdb/_search
{
"query": {
"term": {
"desc": {
"value": "狂神说Java desc1"
}
}
}
}
(11).多个值匹配精确查询
多个值的精确查询
GET testdb/_search
{
"query": {
"bool": {
"should": [
{
"term": {
"t1": {
"value": "22"
}
}
},
{
"term": {
"t1": {
"value": "33"
}
}
}
]
}
}
}
(12).高亮查询
- 高亮查询
"highlight": {
"fields": {
"name":{} 给name字段进行操作
}
}
GET jsxs/user/_search
{
"query": {
"match": {
"name": "吉士先生"
}
},
"highlight": {
"fields": {
"name":{}
}
}
}
- 更改高亮样式 (自定义高亮样式)
"highlight": {
"fields": {
"name":{}
}
}
GET jsxs/user/_search
{
"query": {
"match": {
"name": "吉士先生"
}
},
"highlight": {
"pre_tags": "<p class='key' style='color:red'>",
"post_tags": "</p>",
"fields": {
"name":{}
}
}
}
(十)、集成SpringBoot
官网: https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/index.html
1.ElasticSearch依赖
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.6.2</version>
</dependency>
2.初始化ElasticSearch
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http"),
new HttpHost("localhost", 9201, "http")));
client.close();
3.分析这个类的方法
(1).创建一个空项目
(2).在空项目中创建SpringBOOT模块
选择NoSQL的 es依赖
(3).配置JDK版本
因为我们是新建的空项目所以要用 JDK8 版本
4.配置基本的项目
问题: 一定要保证我们的导入的依赖和我们的E下载ES版本一致。
我们本地的版本是 7.6.2.
(1).解决版本不一致问题
如果我们在构想项目的时候自己选用默认的版本我们就需要 自定义版本依赖。否则不需要自定义版本的依赖了。
<!-- 自己定义es版本依赖,保证和本地一致 -->
<elasticsearch.version>7.6.2</elasticsearch.version>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.jsxs</groupId>
<artifactId>Jsxs-es-api-01</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Jsxs-es-api-01</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<!-- 自己定义es版本依赖,保证和本地一致 -->
<elasticsearch.version>7.6.2</elasticsearch.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>2.7.9</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
(2).配置配置类文件
package com.jsxs.config;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author Jsxs
* @Date 2023/6/27 11:21
* @PackageName:com.jsxs.config
* @ClassName: ElasticSearchClientConfig
* @Description: TODO
* @Version 1.0
*/
@Configuration
public class ElasticSearchClientConfig {
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http")));
return client;
}
}
5.基本的索引 API操作 ⭐
(1).创建索引
package com.jsxs;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.io.IOException;
import static org.elasticsearch.client.RequestOptions.*;
@SpringBootTest
class JsxsEsApi01ApplicationTests {
@Resource
private RestHighLevelClient restHighLevelClient;
// 测试索引的创建 Request
@Test
void testCreateIndex() throws IOException {
// 1.创建一个索引叫做 kuang_index的索引对象请求
CreateIndexRequest request = new CreateIndexRequest("kuang_index");
// 2.执行创建索引的请求 获得响应
CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, DEFAULT);
System.out.println(createIndexResponse);
}
}
(2).获取-删除 索引
package com.jsxs;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.io.IOException;
import static org.elasticsearch.client.RequestOptions.*;
@SpringBootTest
class JsxsEsApi01ApplicationTests {
@Resource
private RestHighLevelClient restHighLevelClient;
@Test
void contextLoads() {
}
// 测试索引的创建 Request
@Test
void testCreateIndex() throws IOException {
// 1.创建一个索引叫做 kuang_index的索引对象请求
CreateIndexRequest request = new CreateIndexRequest("kuang_index");
// 2.执行创建索引的请求 获得响应
CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, DEFAULT);
System.out.println(createIndexResponse);
}
// 测试获取索引的请求
@Test
void testExistIndex() throws IOException {
// 获取一个索引名叫做kuang_index的索引库
GetIndexRequest request = new GetIndexRequest("kuang_index");
// 2.判断这个索引库是否存在?
boolean exists = restHighLevelClient.indices().exists(request, DEFAULT);
System.out.println(exists);
}
// 删除指定的索引
@Test
void testDeleteIndex() throws IOException {
DeleteIndexRequest request = new DeleteIndexRequest("jsxs");
AcknowledgedResponse delete = restHighLevelClient.indices().delete(request, DEFAULT);
System.out.println(delete.isAcknowledged());
}
}
6.基本的文档API操作 ⭐
<!-- 引入我们的JSON包 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.26</version>
</dependency>
(1).新增文档
package com.jsxs;
import com.alibaba.fastjson2.JSON;
import com.jsxs.pojo.User;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.io.IOException;
import static org.elasticsearch.client.RequestOptions.*;
@SpringBootTest
class JsxsEsApi01ApplicationTests {
@Resource
private RestHighLevelClient restHighLevelClient;
// 测试添加文档
@Test
void testAddDocument() throws IOException {
// 1.创建添加的对象
User user = new User("吉士先生", 3);
// 2.创建索引请求操作
IndexRequest request = new IndexRequest("kuang_index");
// 3.规则 put 添加文档
// /索引/表/id
request.id("1"); // 设置索引的id
request.timeout(TimeValue.timeValueSeconds(1)); //设置过期时间为1秒
// 4.将我们的数据放入请求 json
request.source(JSON.toJSONString(user), XContentType.JSON);
// 5.客户端发送请求
IndexResponse index = restHighLevelClient.index(request, DEFAULT);
// 6.
System.out.println(index.toString());
System.out.println(index.status());
}
}
(2).查看文档 (是否存在)
package com.jsxs;
import com.alibaba.fastjson2.JSON;
import com.jsxs.pojo.User;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.io.IOException;
import static org.elasticsearch.client.RequestOptions.*;
@SpringBootTest
class JsxsEsApi01ApplicationTests {
@Resource
private RestHighLevelClient restHighLevelClient;
// 获取文档,判断是否存在 get /索引/doc/id
@Test
void testIsExists() throws IOException {
GetRequest getRequest = new GetRequest("kuang_index", "1");
// 不获取返回的 _source 的上下文了。
getRequest.fetchSourceContext(new FetchSourceContext(false));
getRequest.storedFields("_none_");
// 判断文档是否存在
boolean flag = restHighLevelClient.exists(getRequest, DEFAULT);
System.out.println(flag);
}
}
(3).查看文档 (数据)
// 获取文档,判断是否存在 get /索引/doc/id
@Test
void testGetValue() throws IOException {
GetRequest getRequest = new GetRequest("kuang_index", "1");
// 1.客户端请求获得数据
GetResponse getResponse = restHighLevelClient.get(getRequest, DEFAULT);
// 2.打印我们的信息
System.out.println(getResponse.getSourceAsString());
}
(4).修改文档
根据索引和id
// 更新文档数据.
@Test
void testUpdateValue() throws IOException {
// 1.更新索引为kuang_index的id为1的文档
UpdateRequest request = new UpdateRequest("kuang_index", "1");
// 2.设置超时的时间
request.timeout("1s");
User user = new User("aaaa", 111);
// 3.第一个参数是: 转换为JSON对象,第二个参数是告诉别人我们是一个JSON类型
request.doc(JSON.toJSONString(user),XContentType.JSON);
// 4.客户端请求修改得数据
UpdateResponse update = restHighLevelClient.update(request, DEFAULT);
// 5.打印我们的信息
System.out.println(update.toString());
}
(5).删除文档
// 删除文档的记录
@Test
void testDeleteRequest() throws IOException {
DeleteRequest request = new DeleteRequest("kuang_index", "1");
// 1.假如请求超过1秒的话,那么就不再链接
request.timeout("1s");
// 2.请求客户端
DeleteResponse delete = restHighLevelClient.delete(request, DEFAULT);
// 3.打印信息
System.out.println(delete.toString());
}
(6).批量(添加/删除/修改)文档
@Test
void testBulkRequest() throws IOException {
BulkRequest bulkRequest = new BulkRequest();
// 1.设置超时的时间
bulkRequest.timeout("10s");
// 2.利用链表存储数据
ArrayList<User> users = new ArrayList<>();
users.add(new User("jsxs1",1));
users.add(new User("jsxs2",2));
users.add(new User("jsxs3",3));
users.add(new User("jsxs4",4));
users.add(new User("jsxs5",5));
users.add(new User("jsxs6",6));
users.add(new User("jsxs7",7));
users.add(new User("jsxs8",8));
users.add(new User("jsxs9",9));
users.add(new User("jsxs10",10));
// 3.批量添加的操作
for (int i = 0; i < users.size(); i++) {
// 批量更新和删除就在这里有一个区别 ⭐
bulkRequest.add(new IndexRequest("kuang_index")
.id(""+i+1)
.source(JSON.toJSONString(users.get(i)),XContentType.JSON)
);
}
// 4.客户端请求
BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, DEFAULT);
System.out.println(bulk.toString());
}
(7). 查询 ⭐⭐⭐⭐
在大公司里面 索引库都是放在常量中的
package com.jsxs.utils;
/**
* @Author Jsxs
* @Date 2023/6/27 20:06
* @PackageName:com.jsxs.utils
* @ClassName: ESconst
* @Description: TODO
* @Version 1.0
*/
public class EsConst {
// 我们在工作的时候 尽量把常用的数据设置为常量。
public static final String INDEX="kuang_index";
}
// 查询
@Test
void testSearch() throws IOException {
// 1. 指定去哪个索引库中查找数据 ⭐
SearchRequest request = new SearchRequest(EsConst.INDEX);
//-----------------------------------------------------------------
// 2. 构建搜索的条件 ⭐⭐
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 精确匹配 - 我们可以使用QueryBuilders工具类来实现..
TermQueryBuilder query = QueryBuilders.termQuery("name", "jsxs1");
// 匹配所有 -
MatchAllQueryBuilder query1 = QueryBuilders.matchAllQuery();
// 查询
sourceBuilder.query(query1);
// 时间过时操作
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//-----------------------------------------------------------------
//3. 放入请求中 ⭐⭐⭐
request.source(sourceBuilder);
// 4. 客户端进行请求 ⭐⭐⭐⭐
SearchResponse search = restHighLevelClient.search(request, DEFAULT);
System.out.println(JSON.toJSONString(search.getHits()));
System.out.println("-----------------");
// 打印所有的数据 ⭐⭐⭐⭐⭐
for (SearchHit hit : search.getHits().getHits()) {
System.out.println(hit.getSourceAsMap());
}
}
7.全部的代码
package com.jsxs;
import com.alibaba.fastjson2.JSON;
import com.jsxs.pojo.User;
import com.jsxs.utils.EsConst;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import static org.elasticsearch.client.RequestOptions.*;
@SpringBootTest
class JsxsEsApi01ApplicationTests {
@Resource
private RestHighLevelClient restHighLevelClient;
@Test
void contextLoads() {
}
// 测试索引的创建 Request
@Test
void testCreateIndex() throws IOException {
// 1.创建一个索引叫做 kuang_index的索引对象请求
CreateIndexRequest request = new CreateIndexRequest("kuang_index");
// 2.执行创建索引的请求 获得响应
CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, DEFAULT);
System.out.println(createIndexResponse);
}
// 测试获取索引的请求
@Test
void testExistIndex() throws IOException {
// 获取一个索引名叫做kuang_index的索引库
GetIndexRequest request = new GetIndexRequest("kuang_index");
// 2.判断这个索引库是否存在?
boolean exists = restHighLevelClient.indices().exists(request, DEFAULT);
System.out.println(exists);
}
// 删除指定的索引
@Test
void testDeleteIndex() throws IOException {
DeleteIndexRequest request = new DeleteIndexRequest("jsxs");
AcknowledgedResponse delete = restHighLevelClient.indices().delete(request, DEFAULT);
System.out.println(delete.isAcknowledged());
}
// 测试添加文档
@Test
void testAddDocument() throws IOException {
// 1.创建添加的对象
User user = new User("吉士先生", 3);
// 2.创建索引请求操作
IndexRequest request = new IndexRequest("kuang_index");
// 3.规则 put 添加文档
// /索引/表/id
request.id("1"); // 设置索引的id
request.timeout(TimeValue.timeValueSeconds(1)); //设置过期时间为1秒
// 4.将我们的数据放入请求 json
request.source(JSON.toJSONString(user), XContentType.JSON);
// 5.客户端发送请求
IndexResponse index = restHighLevelClient.index(request, DEFAULT);
// 6.
System.out.println(index.toString());
System.out.println(index.status());
}
// 获取文档,判断是否存在 get /索引/doc/id
@Test
void testIsExists() throws IOException {
GetRequest getRequest = new GetRequest("kuang_index", "1");
// 不获取返回的 _source 的上下文了。
getRequest.fetchSourceContext(new FetchSourceContext(false));
getRequest.storedFields("_none_");
// 客户端判断文档是否存在
boolean flag = restHighLevelClient.exists(getRequest, DEFAULT);
System.out.println(flag);
}
// 获取文档 get /索引/doc/id
@Test
void testGetValue() throws IOException {
GetRequest getRequest = new GetRequest("kuang_index", "1");
// 1.客户端请求获得数据
GetResponse getResponse = restHighLevelClient.get(getRequest, DEFAULT);
// 2.打印我们的信息
System.out.println(getResponse.getSourceAsString());
}
// 更新文档数据.
@Test
void testUpdateValue() throws IOException {
// 1.更新索引为kuang_index的id为1的文档
UpdateRequest request = new UpdateRequest("kuang_index", "1");
// 2.设置超时的时间
request.timeout("1s");
User user = new User("aaaa", 111);
// 3.第一个参数是: 转换为JSON对象,第二个参数是告诉别人我们是一个JSON类型
request.doc(JSON.toJSONString(user),XContentType.JSON);
// 4.客户端请求修改得数据
UpdateResponse update = restHighLevelClient.update(request, DEFAULT);
// 5.打印我们的信息
System.out.println(update.toString());
}
// 删除文档的记录
@Test
void testDeleteRequest() throws IOException {
DeleteRequest request = new DeleteRequest("kuang_index", "1");
// 1.假如请求超过1秒的话,那么就不再链接
request.timeout("1s");
// 2.请求客户端
DeleteResponse delete = restHighLevelClient.delete(request, DEFAULT);
// 3.打印信息
System.out.println(delete.toString());
}
// 批量添加的操作
@Test
void testBulkRequest() throws IOException {
BulkRequest bulkRequest = new BulkRequest();
// 1.设置超时的时间
bulkRequest.timeout("10s");
// 2.利用链表存储数据
ArrayList<User> users = new ArrayList<>();
users.add(new User("jsxs1",1));
users.add(new User("jsxs2",2));
users.add(new User("jsxs3",3));
users.add(new User("jsxs4",4));
users.add(new User("jsxs5",5));
users.add(new User("jsxs6",6));
users.add(new User("jsxs7",7));
users.add(new User("jsxs8",8));
users.add(new User("jsxs9",9));
users.add(new User("jsxs10",10));
// 3.批量添加的操作
for (int i = 0; i < users.size(); i++) {
bulkRequest.add(new IndexRequest("kuang_index")
.id(""+i+1)
.source(JSON.toJSONString(users.get(i)),XContentType.JSON)
);
}
// 4.客户端请求
BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, DEFAULT);
System.out.println(bulk.toString());
}
// 查询
@Test
void testSearch() throws IOException {
// 1. 指定去哪个索引库中查找数据 ⭐
SearchRequest request = new SearchRequest(EsConst.INDEX);
//-----------------------------------------------------------------
// 2. 构建搜索的条件 ⭐⭐
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 精确匹配 - 我们可以使用QueryBuilders工具类来实现..
TermQueryBuilder query = QueryBuilders.termQuery("name", "jsxs1");
// 匹配所有 -
MatchAllQueryBuilder query1 = QueryBuilders.matchAllQuery();
// 查询
sourceBuilder.query(query1);
// 时间过时操作
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//-----------------------------------------------------------------
//3. 放入请求中 ⭐⭐⭐
request.source(sourceBuilder);
// 4. 客户端进行请求 ⭐⭐⭐⭐
SearchResponse search = restHighLevelClient.search(request, DEFAULT);
System.out.println(JSON.toJSONString(search.getHits()));
System.out.println("-----------------");
// 打印所有的数据 ⭐⭐⭐⭐⭐
for (SearchHit hit : search.getHits().getHits()) {
System.out.println(hit.getSourceAsMap());
}
}
}