【ES】Elastic Search
互联网上常见的查询包括:【文章】【视频】【图片】【网站信息】
根据以上数据的格式,我们会分为三个大类:↓↓↓
【结构化数据】【非结构化数据】【半结构化数据】
结构化数据
指像MySQL的表结构所组成的数据,可查询可使用索引对查询进行优化,但是这是有缺点的比如我们想要扩展结构,那么就是比较麻烦的。

非结构化数据
常见的非结构化数据就是无法使用表格来表达的数据,比如通讯记录、文档、报表、视频、图片、这一类的,一般这一类的数据都保存在NoSQL数据库当中,比如MongDB、Redis这一类的,一般都是使用K\V来保存的就是key和value,这样通过key来查找数据是非常快的。

半结构化数据
那么什么是半结构化数据,这一类的数据往往就是配置一类的,比如xml文件和html文件这一类的文件往往放到MongDB、Redis这一类的,缺点就是我们想要查询文件内的内容是很麻烦的。

1. Elastic Stack的核心理论
ES是一个分布式、RESTful风格的搜索和数据分析引擎,往往ES是与Logstash和Kibana一起称之为【ELK Stack】技术栈,ES可以几乎实时的存储、检索数据,本身扩展性很好,可以扩展几百台服务器,处理PB级别的数据量。
**ES:**存储并且搜索数据的项目
**Beats 和 Logstash:**采集和传输的数据项目
**Kibana:**展示数据的项目
常见的ES作用的例子:
全文搜索引擎【百度】
电商的商品搜索【淘宝】
为什么选择ES:
- 同样是分布式的,可以更好的兼容现在的分布式架构扩展性好
- 可以对数据使用监控和指标
- 除了搜索文本还可以分析查询结果
1.1 ES的分片和副本是什么
分片Shards:一个Lucene索引我们在Elasticasearch称作分片,一个ES的索引index是分片的集合,当ES在索引中搜索的时候,他会发送查询到每个属于索引的分片,然后合并倒一个全局的结果集。
分片很重要:
水平分割,扩展我们的内容容量
可以在分片上执行分布式,并行的操作,提高性能/吞吐量
创建的时候指定分片数量,这决定了数据的路由规则,索引不支持在运行中的索引动态修改,副本可以修改。
副本Replicas:ES允许你创建一个或多个备份拷贝,这拷贝叫做副本分片,目的就是解决在某个分片或者节点出问题的时候,提供故障转移机制,因为搜索可以在所有的副本上进行。
分片/节点失败的情况下,提供高可用性,因为这个原因,注意到副本分片从不与主分片至于同一个节点上这个是非常重要的。
扩展的搜索量/吞吐量。
2. ES的入门准备环境
我们将Windows版本的基础版本环境部署完成之后,后期我们会学习使用docker镜像来管理和安装ES。
2.1 下载ES的Window版本

这里我们使用的**ES版本为7.8.0**与教学视频的ES版本一致,为了更方便、更好的入手

2.2 下载ES的mac版本
解压ES 8 然后我们进入config进行配置
配置jvm.options
#设置es启动运行1g
-Xms1g
-Xmx1g
配置yaml文件
cluster.name: my_elastiicsearch #es的名称
network.host: 127.0.0.1 #本地网络地址
http.port: 9200 #端口地址
#我也不知道是啥反正必须设置
http.cors.enabled: true
http.cors.allow-origin: "*"
ingest.geoip.downloader.enabled: false
xpack.security.http.ssl:
enabled: false #这里设置false
xpack.security.enabled: false #这里也设置成false
选择双击打开,不能使用root打开哦。
2.3 如何启动
在Window环境如何启动呢?我们下载完成Windows版本的ES之后我们打开bin脚本,然后启动【elasticsearch.bat】文件

若启动中闪退则我们手动进入ES的bin包 -》 鼠标点击空白处 -》 按住shift + 右键 -》 此处打开Powershell窗口 -》 输入 ./elasticsearch.bat
一般情况下三种闪退情况:
内存不够进入config选择jvm.options然后配置启动为1G
启动的时候不建议使用JDK1.8容易失败,可以选择配置电脑环境变量将JAVA_HOME改成它自带的jdk
查看错误日志是否有Likely root cause:/elasticsearch.keystore.tmp 删除即可
2.4 如何检测启动成功
默认启动则会以9300端口为ES集群间通信端口,9200端口为当前浏览器前端访问协议RESTful端口。
http://localhost:9200/

3. ES倒排索引
数据格式:
ES的数据格式是面向文档型数据库,一条数据在这里就属于一个文档
MySQL -> ES
数据库 -> Index(索引)
表 -> Type(类型)
行 -> Documents(文档)
列 -> Fields(字段)

(3.1)什么是倒排索引?
什么是倒排索引,既然有倒排索引肯定有正排索引,我们使用MySQL进行查询的时候,会设置ID为主键然后设置索引,这样就可以通过ID快速获取内容,这就是正排索引,但是如果我们此时,需要知道内容里包含了什么特定的值呢?比如内容中是否包含【张三】,这样如果使用正排索引的话就会很慢,先找到主键ID的内容然后再遍历内容查看是否包含【张三】这就效率很拉胯。
所以BB了半天什么是倒排索引,倒排索引就是将我们的内容关键字来绑定ID,往往我们一个内容【keyword】可以有很多ID,因为这个内容不可能只有这一个ID拥有,打个比方关键内容【你好】的ID绑定的就有可能有好几十个ID,这就是倒排索引,在ES中表的概念就被弱化了,可以慢慢的被遗忘掉了。
(3.2)索引的创建
我们对比关系型数据库,创建索引【index】就等同于MySQL创建数据库
通过发送【PUT】请求到127.0.0.1:9200就可以创建属于ES的“数据库”了其实就是ES的索引
可以使用Postman或者国产的ApiPost来模拟发送PUT请求

地址:http://localhost:9200/shopping
类型:PUT
解释:创建ES的索引,索引的名称叫做shopping
因为PUT请求有幂等性,所以当创建了一个之后再次创建就会报错,会提示已经有了shopping就无法创建。

那么如果我们使用POST请求呢,也会报错,因为POST请求没有幂等性会报错。

(3.4)索引的分词
注意只有type类型是text的可以进行分词,那么分词的含义就是将一个词拆分, match_phase:会对输入做分词,但是需要结果中也包含所有的分词,而且顺序要求一样。
以"hello world"为例,要求结果中必须包含hello和world,而且还要求他们是连着的,顺序也是固定的,hello that word不满足,world hello也不满足条件。
{
"properties": {
"id": {
"type": "keyword",
"index": true
},
"biz_id": {
"type": "keyword",
"index": true
},
"case_id": {
"type": "keyword",
"index": true
},
"title": {
"type": "text",
"analyzer":"ik_max_word", //这就是对title进行细颗粒度的分词
"index": true
},
"data": {
"type": "text",
"analyzer":"ik_max_word",//这就是对data进行细颗粒度的分词
"index": true
}
}
}
analyzer:创建索引使用的分词器
search_analyzer:查询时使用的分词器
analyzer与search_analyzer的两者的区别
"data": {
"type": "text",
"analyzer":"ik_max_word",//这就是对data进行细颗粒度的分词
"search_analyzer":"ik_smart",//查询用的分词
"index": true
}
下载之后解压然后放到es文件夹的plugins中
然后重启ES即可在控制台查看是否运行成功分词器
4. ES索引的操作
我们上面执行了创建ES索引,那么我们想要查看、删除、查看全部索引呢?
(4.1)查看索引
跟上面的方法一样,我们使用PUT进行创建,可以使用GET方法获取查看,所以将请求换成GET即可

地址:http://localhost:9200/shopping
类型:GET
解释:查看ES的索引,索引的名称叫做shopping
(4.2)查看全部索引
查看全部的索引比较麻烦我们还是GET请求然后路径改为/_cat/indices?v这样就可以了

地址:http://localhost:9200/_cat/indices?v
类型:GET
解释:查看ES的全部索引会返回当前所有索引的状态、监控、UUID、等…
(4.3)删除索引
删除索引则将请求类型修改为DELETE类型即可以删除,请求的路径就是我们要删除索引的名称

地址:http://localhost:9200/shopping
类型:DELETE
解释:删除指定的索引
5. ES文档的操作
同样在ES中创建文档等同于在数据库添加数据,只是ES每条数据都等同于文档,上面我们有说过这个话题。
(5.1)创建ES文档
就是向ES中添加数据,也是使用请求直接进行添加,添加数据的时候使用POST请求进行添加,然后使用数据索引/_doc接口加上JSON数据进行添加

地址:http://localhost:9200/shopping/_doc
类型:POST
解释:向指定的索引【shopping】添加JSON数据
数据:
{ "title": "手机", "category":"华为", "images":"http://www.gulixueyuan.com/xm.jpg", "price":"4899.00" }
(5.2)自定义ES文档ID
我们通过上面的创建ES文档会发现他们的ID是自动生成的,ID很复杂很随机,那么我们是可以通过ID来查找ES的文档内的但是,很麻烦,所以我们是可以自定义ES的文档ID的
那么如何自定义索引呢?在我们的请求shopping/_doc/输入id很简单吧

地址:http://localhost:9200/shopping/_doc/1001
类型:POST
解释:向指定的索引【shopping】添加JSON数据,并且自定义文档的id
数据:
{ "title": "手机2", "category":"华为2", "images":"http://www.gulixueyuan.com/xm.jpg", "price":"4899.00" }
(5.3)扩展知识
1. 我们请求的时候若是<font color='red'>自定义ID的话可以使用POST请求以及PUT请求</font>,因为当我们指定了ID那么将会是幂等性的,则不会重复,所以可以使用PUT。
1. 我们在创建ES的文档的时候可以使用<font color='red'>_doc</font>也可以使用 <font color='red'> _create</font>

(5.4)文档的查询
创建了ES文档,我们还得查询文档,先使用主键来查询内容,跟主键创建文档是一样的,只是将POST和PUT请求转换成了GET请求

地址:http://localhost:9200/shopping/_doc/1001
类型:GET
解释:根据主键的ID或者自定义的ID进行数据的查询
(5.5)文档全查
我们上面是根据主键查询,一次只能查询一个那么我们想要全查呢?那该怎么办?我们将/_doc改为 _search就可以全查了

地址:http://localhost:9200/shopping/_search
类型:GET、POST
解释:全查询将结果全部展示出来
(5.6)全量修改
什么是全量修改,全量修改往往我们需要获取这个数据的所有参数,然后进行修改之后在传过去,若没有传修改参数则会直接缺失了这个参数,好处是可以删除某个文档的字段。

我们使用全量修改这次少传个参数title删除掉然后传参过去
然后我们查看修改之后的结果,你以为的是,没传参的参数没有被修改该,但是实际上没传参的参数被删除了。
地址:http://localhost:9200/shopping/_doc/1001
类型:PUT
解释:根据主键查询并且全量修改参数,若未指定参数则会将该参数移除
参数:
{ // "title": "电脑", "category":"鸿蒙", "images":"http://www.gulixueyuan.com/xm.jpg", "price":"8955.00" }
(5.7)局部修改
局部修改这里的局部修改则是将整条参数的部分进行修改,比上面的修改方式更加的人性化,但是这个是使用POST请求进行修改的,然后我们请求地址/_update/就可以了,局部修改的参数必须增加doc字段,然后加上我们要修改的参数,若没有这个参数则会增加这个参数
地址:http://localhost:9200/shopping/_update/1001
类型:POST
解释:根据主键查询并且局部修改参数,并且参数需要增加doc字段
参数:
{ "doc":{ "title":"中国华为!!" } }
(5.8)文档删除
根据ID删除文档,使用接口_doc/id然后使用DELETE请求进行删除操作

地址:http://localhost:9200/shopping/_doc/1001
类型:DELETE
解释:根据主键查询并且删除改参数。
6. ES文档的查询
ES核心就是查询,上面只是开胃菜,我们现在开始正式入门到查询,常见的查询有条件查询、分页查询、查询排序等等…
**全局查询:**http://localhost:9200/shopping/_search
(6.1)条件查询
条件查询则是在全查询的基础上使用问号拼接然后+q进行筛选
例子:http://localhost:9200/shopping/_search?q=xxx:xx

地址:http://localhost:9200/shopping/_search?q=category:小米
类型:GET
参数:q=category:小米
解释:使用问号出传参,根据q查询所传参的不同进行模糊查询,这样查询有缺点比较是直接在地址栏使用中文传参会乱码,所以下面有参数查询。

地址:http://localhost:9200/shopping/_search
类型:GET
参数:
{ "query":{ "match":{ "category":"小米" } } }解释:使用参数体传参query字段JSON进行查询,这样使用参数查询不会产生乱码,地址栏传参有可能会有乱码。
(6.2)全查询、分页查询
分页查询的前提是全查询,这种全查询跟上面的不一样,这种全查是带参数的全查询。

地址:http://localhost:9200/shopping/_search
类型:GET
参数:
{ "query":{ "match_all":{ } } }解释:这个是全查询,该全查询调用的是查询接口使用直接传参的形式进行访问,上面有全查询了为何这里还要展示另外一个全查询,分页查询就是在这个全查询的基础上建立的。
分页查询
在全查询的基础之上我们传入form和size参数用来实现分页查询的功能

地址:http://localhost:9200/shopping/_search
类型:GET
参数:
{ "query":{ "match_all":{ } }, "from": 0, "size": 2 }解释:这个是分页查询是在全查询的基础之上创建的,使用from参数指定起始位置最小值为0和size参数指定一页多少数据。
(6.3)分页查询常见问题
例子:若你现在想要第二页的数据,但是当前页面必须是2条数据,那么你如何查询?
你或许会直接传参为以下样式:
{ "query":{ "match_all":{ } }, "from": 1, "size": 2 }说明:你以为from是页数第二页,其实不是,这里的size的确是每个页有多少条数据,但是这里的from并不是指的第二页,只是指的是起始位置,若想指明第二页的话有一个公式。
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑错误的↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓正确的↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
这样传参就正确了,为何第二页我们传参为from为2呢?不是默认从0开始么?为什么不是1呢?这就解释一下为何是传这个参数。
{ "query":{ "match_all":{ } }, "from": 2, "size": 2 }**解析:**记住公式 (页码 - 1) * 每页数据条数
若此时你需要一页8条数据,然后当前必须为第5页,那么我们带入公式即可展示正确页码的数据from的值
(5 - 1) * 8 = 32 那么我们以上案例则必须from值为32。
(6.4)分页查询指定结果
查询的过程中我们每次分页查询会发现它将这个数据的所有信息都展示了,我们比如只想要这个数据的title字段呢?我们想要数据的指定字段,就可以使用以下的方法。

地址:http://localhost:9200/shopping/_search
类型:GET
参数:
{ "query":{ "match_all":{ } }, "from": 0, "size": 2, "_source" : ["title"] }解释:这个是分页查询是在全查询的基础之上创建的,我们指定需要某些字段就使用中括号框起来即可,增加上_source字段即可这样修饰将需要字段查询,处理,多个字段使用逗号隔开如下演示
"_source" : ["title","category"]
(6.4)分页升、降排序查询
我们既然可以分页、全查、当然也可以排序查询,我们可以使用sort字段指定我们需要排序的字段进行排序。

地址:http://localhost:9200/shopping/_search
类型:GET
参数:
{ "query":{ "match_all":{ } }, "from": 0, "size": 2, "_source" : ["title","category"], "sort" : { //这里因为使用的price是text类型所以必须增加.keyword字段 "price.keyword" : { "order": "asc" } } }解释:这个是分页查询是在全查询的基础之上创建的,我们使用sort进行排序,根据price【价格】进行排序,然后我们使用系统的参数order根据正序【desc】还是倒叙【asc】进行排序。
为何price字段多了一个.keyword,因为我们进行排序的时候默认只能根据数字类型的进行排序,但是我们这里默认创建的时候设置的类型为text所以无法根据字符串查询,只能通过.keyword后缀进行查询。
(6.5)多条件复杂查询
与查询【and】
多条件的情况下实现查询,比如SQL里面的或(or)查询和与(and)查询在ES中都是使用【must 是 and】和【should 是 or】来表达。

地址:http://localhost:9200/shopping/_search
类型:GET
参数:
{ "query":{ "bool":{ //与查询 "must":[ { "match":{ "category":"小米" } }, { "match":{ "price": "6999.00" } } ] } } }解释:多条件的情况下,我们常常使用bool来括起来,然后我们根据需要的结果设置and查询或or查询两种查询方式,多查询的结果下都是以数组传入JSON字段的,比如must:[ ] 这个括号是中括号就是可以放很多个JSON的条件的。
其中 must 【and与查询】 should【or或查询】
或查询【or】
【should 是 or】来表达我们常见的SQL中的or查询

地址:http://localhost:9200/shopping/_search
类型:GET
参数:
{ "query":{ "bool":{ //或查询 "should":[ { "match":{ "category":"小米" } }, { "match":{ "category": "华为" } } ] } } }解释:这个与上面的查询差不多,上面的是and查询这个是or查询,查询结果为【小米】或【华为】,所以这两者任意一个都可以显示。
其中 must 【and与查询】 should【or或查询】
(6.6)范围查询
如果我们想要进行范围查询的话可以直接使用filter字段加上range进行范围的把控

地址:http://localhost:9200/shopping/_search
类型:GET
参数:
{ "query":{ "bool":{ "filter":{ "range":{ "price":{ //大于5000 "gt": 5000 } } } } } }解释:使用filter进行过滤然后我们设置范围range,指定price字段gt(大于)5000的进行筛选。
(6.7)全文索引与完全匹配
首先我们需要知道一个事情就是,ES查询的时候使用的是【分词】查询,说白了你输入【华为】它是根据“华”字段全文搜索加上“为”字段全文搜索,我们的商品有【小米、华为】那么我们输入【小华】,注意这个里面包含了【小米的小】和【华为的华】字,那么搜索的时候会将【小米】和【华为】都进行展示!

地址:http://localhost:9200/shopping/_search
类型:GET
参数:
{ "query":{ "match":{ "category":"小华" } } }解释:ES是分段查询,会将【小华】拆字查询,将【小】和【华】进行全文的模糊查询,得出所有符合的结果然后展示。
完全匹配查询
如何实现完全匹配呢,就是我输入【小华】那么只搜索【小华】而不去将其拆开搜索【小】和【华】这些字段呢?那么很简单将我们的match后缀增加上_phrase字段。

地址:http://localhost:9200/shopping/_search
类型:GET
参数:
{ "query":{ "match_phrase":{ "category":"小华" } } }解释:ES是分段查询,我们将match后增加_phrase就可以开启完全匹配查询
(6.8)高亮查询
我们要是想要对查询的结果进行显示,并且高亮的话,我们可以增加highlight字段和fields字段然后指定我们的需要高亮的字段,这里生成的高亮为为倾斜

地址:http://localhost:9200/shopping/_search
类型:GET
参数:
{ "query":{ "match_phrase":{ "category":"小米" } }, //开启高亮显示 "highlight":{ "fields":{ "category":{} } } }解释:使用普通的查询筛选结果为小米,然后我们通过highlight字段指定进行fields高亮查询,然后我们指定我们需要高亮的字段,我们可以使用title、price、images、category等等这些我们自己的传入的字段进行高亮
(6.8)聚合分组查询
什么是聚合分组查询?其实就是SQL中的group的分组方法,我们使用aggs字段加上terms字段和field进行分组,默认为将原始的数据也查出来。

地址:http://localhost:9200/shopping/_search
类型:GET
参数:
{ "aggs":{ //聚合操作 "price_group":{ //分组名称这里随意起名 "terms":{ //分组 "field": "price.keyword" //被分组的字段,我们是text格式必须增加.keyword } } } }解释:使用聚合查询aggs进行,我们将这次的查询名称修改为price_group该名称可以随意,然后使用分组函数terms进行分组,最后将答案展示出来,因为price为text字段所以我们需要绑定.keyword进行分组
图中的返回字段有key这就是我们的结果,有doc_count这就是分组之后的结果,说明有多个组在一起参数一样。
注意:我们上面的答案是有原始数据的,并不完全是分组之后的数据,我们可以增加一个字段,使其不显示原始的数据哦
{ "aggs":{ //聚合操作 "price_group":{ //分组名称这里随意起名 "terms":{ //分组 "field": "price.keyword" //被分组的字段,我们是text格式必须增加.keyword } } }, "size": 0 //将原始数据的长度显示修改为0这样就不会显示原始数据了 }
(6.9)分组平均值查询
跟上面的聚合分组差不多,只是将其中的terms函数修改为avg平均值函数而已

地址:http://localhost:9200/shopping/_search
类型:GET
参数:
{ "aggs":{ "price_avg":{ "avg":{ //平均值获取 "field": "price" } } } }解释:这里分组直接替换为avg但是会出错,还是因为之前指定的字段有问题,所以这里其实运行失败了,但是这样的写法和参数并没有问题。
7. ES的映射关系
在MySQL中存在表这种概念,表的概念也包含了字段的类型概念,比如字段是text类型或者int类型这些,那么在ES中也有相同的概念,这种称之为映射关系。
7.1 如何创建映射关系
使用PUT请求县创建我们的文档【类似数据库】,然后创建我们的映射使用_mapping进行创建,然后输入对应的JSON格式的字符串然后使用{}括起来,然后创建properties再将其使用{}括起来即可。

我们先创建一个简单的索引就相当于数据库,名称为user,然后我们在创建结构信息
地址:http://localhost:9200/user
类型:PUT
解释:直接创建所以命名为user。
创建文件映射
创建user索引的文件映射使用_mapping进行映射的创建,并且传参properties将没我们的文件类型括起来。

地址:http://localhost:9200/user/_mapping
类型:PUT
参数:
{ "properties":{ "name":{ //text以分词查询 "type":"text", //可以通过索引找到 "index": true }, "sex":{ //keyword不可以分词查询 "type":"keyword", //可以通过索引找到 "index":true }, "tel":{ //keyword不可以分词查询 "type": "keyword", //不可以通过索引找到 "index": false } } }**解释:**使用_mapping进行创建,并且在我们需要的文档类型种创建对应的映射关系,比如我们需要“name”字段然后我们可以指定类型type,我们设置“text”就可以分词进行查询,若查询不想分词就使用keyword类型,然后我们可以使用可见性,index为索引的可见性,若为false则无法通过查询获取。
7.2 添加映射数据
既然我们上面以及创建好了映射关系,那么我们需要添加映射数据一会进行查询做一个对比,我们可以通过所映射的数据进行查询,添加数据的方法如上面之前添加的方式一样。

地址:http://localhost:9200/user/_create/1003
类型:PUT
参数:
{ "name": "大米", "sex": "女生", "tel": "13938757800" }**解释:**给我们的user索引添加数据,我们这里添加的三条,这里只展示一条数据,添加的数据是自定义的ID
7.3 检索查询数据【分词】
我们刚刚上面已经实现了创建索引和创建数据,现在我们需要查询数据,使用全文检索的方式,就是我们之前经常使用的_search然后增加参数query并且指定我们的条件match为name我的字段名称“小”看不懂如下。
这里的分词是指,根据这个字段的任意一个相同即可匹配,说白了就是模糊查询,只要包含指定的条件字段【小】,所以的含有【小】字段的都符合需求。

地址:http://localhost:9200/user/_search
类型:GET
参数:
{ "query":{ "match":{ //设置为查询为“小” "name": "小" } } }**解释:**使用条件查询【小】,我们查出来【小米】是因为我们设置了分词查询,就是类型为text的所以是可以查询得出来【小米】带有小字的,如果我们去查询sex为【生】的就是【男生、女生】的生那么因为设置的是keyword类型所以无法分词查询,下面展示。
7.4 检索查询数据【不分词】
同理什么是“不分词”就是字段中只要一个不符合要求的,那么就不会展示,比如我们查询字段“sex”那么该字段为【男生】和【女生】,如果是设置不分词,那么输入【男】或者【女】都将不会查出结果。

地址:http://localhost:9200/user/_search
类型:GET
参数:
{ "query":{ "match":{ //设置为查询为“男” "sex": "男" } } }**解释:**使用条件查询【男】,我们可以看出来并没有任何结果,其实我们有参数为【男生】因为是不分词查询的keyword的类型所以无法查出来。
7.5 检索查询数据【无法查询】
设置index为false那么将无法被索引查询。

地址:http://localhost:9200/user/_search
类型:GET
参数:
{ "query":{ "match":{ //设置为查询为“13938757800” "tel": "13938757800" } } }解释:将index设置为false就可以屏蔽索引的查询。
8. Java调用ES
因为ES是Java开发的,我们是可以通过ES的代码API直接调用的这里我们不多阐述,直接创建一个ES的Maven工程即可。

8.1 修改pom文件

引入相关的依赖特别是我们的es依赖,一个是服务器一个是高级的客户端,我们使用高级的客户端
<dependencies>
<!--ES的依赖-->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.8.0</version>
</dependency>
<!--ES的客户端-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.8.0</version>
</dependency>
<!--ES依赖2.x的log4j日志-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.9</version>
</dependency>
<!--junit单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
</dependencies>
8.2 创建主启动程序
我们这次使用是不是SpringBoot项目,所以我们还是将本地的ES客户端打开,并且我们尝试创建一个main主启动类,来调用我们的ES客户端,进行访问。
在Java包上面右击New Class - 输入名称com.wl.es.ES_Client - 完成主启动类 - 输入main调用ES客户端

创建ES的Java客户端并且启动主启动类进行测试。
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import java.io.IOException;
public class ES_Client {
public static void main(String[] args) throws IOException {
//创建客户端
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
System.out.println("创建客户端请稍候...");
//关闭ES
restHighLevelClient.close();
System.out.println("关闭ES客户端请稍后...");
}
}
这样就我们启动main要是没有报错,则表示我们的ES以及连接上了。

8.3 创建log4j2配置
我们上面是引入了log4j2的依赖,但是我们引入了之后并没有进行配置文件的编写,我们创建了索引的时候需要看日志的,所以我们呢现在创建log4j2的配置依赖。
在resources创建文件 – 名称log4j2.xml --输入以下配置即可。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c{1}:%L - %msg%n" />
</Console>
<RollingFile name="RollingFile" filename="log/test.log"
filepattern="${logPath}/%d{YYYYMMddHHmmss}-fargo.log">
<PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c{1}:%L - %msg%n" />
<Policies>
<SizeBasedTriggeringPolicy size="10 MB" />
</Policies>
<DefaultRolloverStrategy max="20" />
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console" />
<AppenderRef ref="RollingFile" />
</Root>
</Loggers>
</Configuration>
8.4 创建索引
我们之前说过创建ES的索引就是创建一个表相当于,所以我们需要创建CreateIndexRequest(“索引名称”);我们创建了就得有反馈,这就是响应操作我们需要使用上面构建好了的ES服务对象restHighLevelClient来调用indices().create(索引对象,默认请求);最后将返回的值调用响应状态进行打印即可。(不明白看下面)

我们先进行全查,可以看出来我们的当前索引只有user和shopping两个对吧
地址:http://localhost:9200/_cat/indices?v
类型:GET
描述:全查索引,我们只有两个,接下来我们使用Java创建第三个索引

生成CreateIndexRequest对象并且指定索引名称【不能有大写】 — 然后我们创建CreateIndexResponse对象 — 使用该参数输入我们的对象restHighLevelClient.indices().create(上面的对象名称, RequestOptions.DEFAULT); — xxx对象.isAcknowledged();调用展示返回值为布尔类型。
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import java.io.IOException;
public class ES_Client {
public static void main(String[] args) throws IOException {
//创建客户端
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
System.out.println("创建客户端请稍候...");
//生成索引对象命名为Java-ES
CreateIndexRequest request = new CreateIndexRequest("java_es");
//构建返回参数使用create并且返回值为默认的DEFAULT
CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
//获取返回的boolean并且输出
boolean acknowledged = createIndexResponse.isAcknowledged();
System.out.println("执行操作: ->" + acknowledged);
//关闭ES
restHighLevelClient.close();
System.out.println("关闭ES客户端请稍后...");
}
}
最后执行完成打印true即可

8.5 索引查询与删除
查询
我们上面执行了索引的创建,这里开始使用索引的查询与删除的操作
右击包 – 创建New Class – 名称ES_index_Search还是先创建RestHighLevelClient类

创建好了之后我们需要创建查询索引的对象,所以需要使用GetIndexRequest(“索引名称”);然后我们使用客户端参数调用indices().get(上面的对象, RequestOptions.DEFAULT);
import org.apache.http.HttpHost;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import java.io.IOException;
public class ES_index_Search {
public static void main(String[] args) throws IOException {
//创建客户端
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
System.out.println("创建客户端请稍候...");
//查询索引java_es
GetIndexRequest getIndexRequest = new GetIndexRequest("java_es");
//获取返回的参数并且打印出来
GetIndexResponse getIndexResponse = restHighLevelClient.indices().get(getIndexRequest, RequestOptions.DEFAULT);
System.out.println("结果打印...");
System.out.println("===================================");
System.out.println(getIndexResponse.getAliases());
System.out.println(getIndexResponse.getMappings());
System.out.println(getIndexResponse.getSettings());
System.out.println("===================================");
//关闭ES
restHighLevelClient.close();
System.out.println("关闭ES客户端请稍后...");
}
}
删除
索引删除的操作,其实想一想也知道,上面我们的查询操作大部分代码前缀都有get将其换成delete即可。

import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import java.io.IOException;
public class ES_index_Delete {
public static void main(String[] args) throws IOException {
//创建客户端
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
System.out.println("创建客户端请稍候...");
//删除索引java_es
DeleteIndexRequest delIndexRequest = new DeleteIndexRequest("java_es");
//获取返回的参数并且打印出来
AcknowledgedResponse delete = restHighLevelClient.indices().delete(delIndexRequest, RequestOptions.DEFAULT);
System.out.println("结果打印...");
System.out.println("=============");
System.out.println(delete.isAcknowledged());
System.out.println("=============");
//关闭ES
restHighLevelClient.close();
System.out.println("关闭ES客户端请稍后...");
}
}
9. 使用linux创建ES索引
//elastic[账号]Z[JD&Z#%j&#oLYY%[密码]
curl -XPUT -u "elastic:Z[JD&Z#%j&#oLYY%"
//查看所有索引
curl -u "elastic:Z[JD&Z#%j&#oLYY%" http://127.0.0.1:9200/_cat/indices?v
//创建索引
curl -XPUT -u "elastic:Z[JD&Z#%j&#oLYY%" -H "Content-Type: application/json" '127.0.0.1:9200/ic_case_index'
//关闭索引
curl -XPOST -u "elastic:Z[JD&Z#%j&#oLYY%" -H "Content-Type: application/json" '127.0.0.1:9200/ic_case_index/_close'
//自定义分词
curl -XPUT -u "elastic:Z[JD&Z#%j&#oLYY%" -H "Content-Type: application/json" '127.0.0.1:9200/ic_case_index/_settings' -d '{"analysis": {"analyzer": {"comma": {"type": "pattern","pattern": ","}}}}'
//打开索引
curl -XPOST -u "elastic:Z[JD&Z#%j&#oLYY%" -H "Content-Type: application/json" '127.0.0.1:9200/ic_case_index/_open'
//查看索引
curl -XGET -u "elastic:Z[JD&Z#%j&#oLYY%" -H "Content-Type: application/json" '127.0.0.1:9200/ic_case_index'
//创建mapping
curl -XPUT -u "elastic:Z[JD&Z#%j&#oLYY%" -H "Content-Type: application/json" '127.0.0.1:9200/ic_case_index/_mapping' -d '{"dynamic": "true","properties": {"id": {"type": "keyword","index": true},"biz_id": {"type": "text","analyzer":"comma","index": true},"case_id": {"type": "text","analyzer":"comma","index": true},"licence_id": {"type": "text","analyzer":"comma","index": true},"credit_code": {"type": "text","analyzer":"comma","index": true},"id_card_code": {"type": "text","analyzer":"comma","index": true},"car_code": {"type": "text","analyzer":"comma","index": true},"ship_code": {"type": "text","analyzer":"comma","index": true},"railway_shift_name": {"type": "text","analyzer":"comma","index": true},"aviation_shift_name": {"type": "text","analyzer":"comma","index": true},"data_type": {"type": "keyword","index": true},"title": {"type": "text","analyzer":"standard","index": true},"brief_introduction": {"type": "text","analyzer":"standard","index": true},"data": {"type": "text","analyzer":"standard","index": true},"info": {"type": "text","analyzer":"standard","index": false}}}'
//插入数据
curl -XPOST -u "elastic:Z[JD&Z#%j&#oLYY%" -H "Content-Type: application/json" '127.0.0.1:9200/ic_case_index/_doc' -d '{}'
//根据json文件批量插入数据----好像写的有问题这个应该不管用
curl -XPOST -u "elastic:Z[JD&Z#%j&#oLYY%" -H "Content-Type: application/json" '127.0.0.1:9200/ic_case_index/_doc' --data-binary @/root/es/demo.json
//查询数据
curl -XGET -u "elastic:Z[JD&Z#%j&#oLYY%" -H "Content-Type: application/json" '127.0.0.1:9200/ic_case_index/_search'
//修改数据
curl -XPUT -u "elastic:Z[JD&Z#%j&#oLYY%" -H "Content-Type: application/json" '127.0.0.1:9200/ic_case_index/_doc/id' -d ''
//删除数据
curl -XDELETE -u "elastic:Z[JD&Z#%j&#oLYY%" -H "Content-Type: application/json" '127.0.0.1:9200/ic_info_index/_doc/id'
//删除索引
curl -XDELETE -u "elastic:Z[JD&Z#%j&#oLYY%" -H "Content-Type: application/json" '127.0.0.1:9200/ic_case_index'
============创建mapping===========
{
"properties": {
"id": {
"type": "keyword",
"index": true
},
"biz_id": {
"type": "text",
"analyzer":"comma",
"index": true
},
"case_id": {
"type": "text",
"analyzer":"comma",
"index": true
},
"licence_id": {
"type": "text",
"analyzer":"comma",
"index": true
},
"credit_code": {
"type": "text",
"analyzer":"comma",
"index": true
},
"id_card_code": {
"type": "text",
"analyzer":"comma",
"index": true
},
"car_code": {
"type": "text",
"analyzer":"comma",
"index": true
},
"ship_code": {
"type": "text",
"analyzer":"comma",
"index": true
},
"railway_shift_name": {
"type": "text",
"analyzer":"comma",
"index": true
},
"aviation_shift_name": {
"type": "text",
"analyzer":"comma",
"index": true
},
"data_type": {
"type": "keyword",
"index": true
},
"title": {
"type": "text",
"analyzer":"standard",
// "analyzer":"ik_max_word",
// "search_analyzer":"ik_smart",//查询用的分词
"index": true
},
"brief_introduction": {
"type": "text",
"analyzer":"standard",
// "analyzer":"ik_max_word",
// "search_analyzer":"ik_smart",//查询用的分词
"index": true
},
"data": {
"type": "text",
"analyzer":"standard",
// "analyzer":"ik_max_word",
// "search_analyzer":"ik_smart",//查询用的分词
"index": true
},
"info": {
"type": "text",
"analyzer":"standard",
"index": false
}
}
}







881

被折叠的 条评论
为什么被折叠?



