欢迎光临散文网 会员登陆 & 注册

分布式搜索引擎Elasticsearch讲解专题(二)

2022-06-23 10:28 作者:指南针毕业设计  | 我要投稿

  今天主要介绍索引库和文档的相关Rest操作,使用PostMan或者Kibbna来进行相关请求接口的调用,实现索引库的创建和维护,文档的添加和维护等。以及使用ES提供的API实现索引库和文档的CRUD操作。

3.索引库操作

索引库就类似数据库表,mAPPing映射就类似表的结构。

我们要向es中存储数据,必须先创建“库”和“表”。


3.1.mAPPing映射属性

mAPPing是对索引库中文档的约束,常见的mAPPing属性包括:



  • type:字段数据类型,常见的简单类型有:




    • 字符串:text(可分词的文本)、keyword(精确值,例如:品牌、国家、ip地址)




    • 数值:long、integer、short、byte、double、float、




    • 布尔:boolean




    • 日期:date




    • 对象:object





  • index:是否创建索引,默认为true,index=true表示均可以参与搜索




  • analyzer:使用哪种分词器




  • properties:该字段的子字段



例如下面的json文档:

对应的每个字段映射(mAPPing):



  • age:类型为 integer;参与搜索,因此需要index为true;无需分词器




  • weight:类型为float;参与搜索,因此需要index为true;无需分词器




  • isMarried:类型为boolean;参与搜索,因此需要index为true;无需分词器




  • info:类型为字符串,需要分词,因此是text;参与搜索,因此需要index为true;分词器可以用ik_smart




  • email:类型为字符串,但是不需要分词,因此是keyword;不参与搜索,因此需要index为false;无需分词器




  • score:虽然是数组,但是我们只看元素的类型,类型为float;参与搜索,因此需要index为true;无需分词器




  • name:类型为object,需要定义多个子属性




    • name.firstName;类型为字符串,但是不需要分词,因此是keyword;参与搜索,因此需要index为true;无需分词器




    • name.lastName;类型为字符串,但是不需要分词,因此是keyword;参与搜索,因此需要index为true;无需分词器




3.2.索引库的CRUD

这里我们统一使用Kibana编写DSL的方式来演示。


3.2.1.创建索引库和映射

基本语法:



  • 请求方式:PUT




  • 请求路径:/索引库名,可以自定义




  • 请求参数:mAPPing映射


格式:


示例:


2.2.2.查询索引库

基本语法



  • 请求方式:GET




  • 请求路径:/索引库名




  • 请求参数:无


格式

 GET /索引库名

2.2.3.修改索引库

倒排索引结构虽然不复杂,但是一旦数据结构改变(比如改变了分词器),就需要重新创建倒排索引,这简直是灾难。因此索引库一旦创建,无法修改mAPPing


虽然无法修改mAPPing中已有的字段,但是却允许添加新的字段到mAPPing中,因为不会对倒排索引产生影响。

语法说明: 

2.2.4.删除索引库

语法:



  • 请求方式:DELETE




  • 请求路径:/索引库名




  • 请求参数:无


格式:

 DELETE /索引库名

2.2.5.总结

索引库操作有哪些?



  • 创建索引库:PUT /索引库名




  • 查询索引库:GET /索引库名




  • 删除索引库:DELETE /索引库名




  • 添加字段:PUT /索引库名/_mAPPing



4.文档操作

4.1.新增文档

语法:

示例:

4.2.查询文档

根据rest风格,新增是post,查询应该是get,不过查询一般都需要条件,这里我们把文档id带上。

语法:

 GET /{索引库名称}/_doc/{id}

通过kibana查看数据:

 GET /znz/_doc/1

#查询所有文档
GET /znz/_search


4.3.删除文档

删除使用DELETE请求,同样,需要根据id进行删除:

语法:

 DELETE /{索引库名}/_doc/id值

示例:

 # 根据id删除数据  DELETE /znz/_doc/1


4.4.修改文档

修改有两种方式:



  • 全量修改:直接覆盖原来的文档




  • 增量修改:修改文档中的部分字段



4.4.1.全量修改

全量修改是覆盖原来的文档,其本质是:



  • 根据指定的id删除文档




  • 新增一个相同id的文档


注意:如果根据id删除时,id不存在,第二步的新增也会执行,也就从修改变成了新增操作了。


语法:

示例:

 

4.4.2.增量修改

增量修改是只修改指定id匹配的文档中的部分字段。

语法:

 


示例:

4.5.总结

文档操作有哪些?



  • 创建文档:POST /{索引库名}/_doc/文档id { json文档 }




  • 查询文档:GET /{索引库名}/_doc/文档id




  • 删除文档:DELETE /{索引库名}/_doc/文档id




  • 修改文档:




    • 全量修改:PUT /{索引库名}/_doc/文档id { json文档 }




    • 增量修改:POST /{索引库名}/_update/文档id { "doc": {字段}}




5.使用API来操作索引库和文档

5.1 创建表结构

5.2 操作索引库

5.2.1  定义其对应的MAPPing映射

为方便引用,我们定义一个常量来存储分析设计的映射结构:

几个特殊字段说明:



  • location:地理坐标,里面包含精度、纬度




  • all:一个组合字段,其目的是将多字段的值 利用copy_to合并,提供给用户搜索.其值在查询时不显示。


地理坐标说明:

编辑

copy_to说明:copy_to指向的字段字段类型要为:text。

编辑

 5.2.2  初始化RestClient

在elasticsearch提供的API中,与elasticsearch一切交互都封装在一个名为RestHighLevelClient的类中,必须先完成这个对象的初始化,建立与elasticsearch的连接。

分为三步:

1)引入es的RestHighLevelClient依赖:


2)因为SpringBoot默认的ES版本是7.6.2,所以我们需要覆盖默认的ES版本:


3)初始化RestHighLevelClient:

初始化的代码如下:


这里为了单元测试方便,我们创建一个测试类HotelIndexTest,然后将初始化的代码编写在@Before方法中:

5.2.3 创建索引库

代码分为三步:



  • 1)创建Request对象。因为是创建索引库的操作,因此Request是CreateIndexRequest。




  • 2)添加请求参数,其实就是DSL的JSON参数部分。因为json字符串很长,这里是定义了静态字符串常量MAPPING_TEMPLATE,让代码看起来更加优雅。




  • 3)发送请求,client.indices()方法的返回值是IndicesClient类型,封装了所有与索引库操作有关的方法。



5.2.4.删除索引库

删除索引库的DSL语句非常简单:

 DELETE /hotel

与创建索引库相比:



  • 请求方式从PUT变为DELTE




  • 请求路径不变




  • 无请求参数


所以代码的差异,注意体现在Request对象上。依然是三步走:



  • 1)创建Request对象。这次是DeleteIndexRequest对象




  • 2)准备参数。这里是无参




  • 3)发送请求。改用delete方法


在hotel-demo中的HotelIndexTest测试类中,编写单元测试,实现删除索引:

5.2.5.判断索引库是否存在

判断索引库是否存在,本质就是查询,对应的DSL是:

 GET /hotel


因此与删除的Java代码流程是类似的。依然是三步走:



  • 1)创建Request对象。这次是GetIndexRequest对象




  • 2)准备参数。这里是无参




  • 3)发送请求。改用exists方法



5.2.5.总结

JavaRestClient操作elasticsearch的流程基本类似。核心是client.indices()方法来获取索引库的操作对象。

索引库操作的基本步骤:



  • 初始化RestHighLevelClient




  • 创建XxxIndexRequest。XXX是Create、Get、Delete




  • 准备DSL( Create时需要,其它是无参)




  • 发送请求。调用RestHighLevelClient#indices().xxx()方法,xxx是create、exists、delete



5.3 操作文档

为了与索引库操作分离,我们再次参加一个测试类,做两件事情:



  • 初始化RestHighLevelClient




  • 我们的酒店数据在数据库,需要利用IHotelService去查询,所以注入这个接口


5.3.1.新增文档

我们要将数据库的酒店数据查询出来,写入elasticsearch中。

数据库查询后的结果是一个Hotel类型的对象。结构如下:

与我们的索引库结构存在差异:



  • longitude和latitude需要合并为location


因此,我们需要定义一个新的类型,与索引库结构吻合:


我们导入酒店数据,基本流程一致,但是需要考虑几点变化:



  • 酒店数据来自于数据库,我们需要先查询出来,得到hotel对象




  • hotel对象需要转为HotelDoc对象




  • HotelDoc需要序列化为json格式


因此,代码整体步骤如下:



  • 1)根据id查询酒店数据Hotel




  • 2)将Hotel封装为HotelDoc




  • 3)将HotelDoc序列化为JSON




  • 4)创建IndexRequest,指定索引库名和id




  • 5)准备请求参数,也就是JSON文档




  • 6)发送请求


在项目的HotelDocumentTest测试类中,编写单元测试:

5.3.2 查询文档

与之前类似,也是三步走:



  • 1)准备Request对象。这次是查询,所以是GetRequest




  • 2)发送请求,得到结果。因为是查询,这里调用client.get()方法




  • 3)解析结果,就是对JSON做反序列化


在项目的HotelDocumentTest测试类中,编写单元测试:


5.3.3.删除文档

删除的DSL为是这样的:

 DELETE /hotel/_doc/{id}

与查询相比,仅仅是请求方式从DELETE变成GET,可以想象Java代码应该依然是三步走:



  • 1)准备Request对象,因为是删除,这次是DeleteRequest对象。要指定索引库名和id




  • 2)准备参数,无参




  • 3)发送请求。因为是删除,所以是client.delete()方法



在项目的HotelDocumentTest测试类中,编写单元测试:

5.3.4 修改文档


与之前类似,也是三步走:



  • 1)准备Request对象。这次是修改,所以是UpdateRequest




  • 2)准备参数。也就是JSON文档,里面包含要修改的字段




  • 3)更新文档。这里调用client.update()方法


在项目的HotelDocumentTest测试类中,编写单元测试:

5.3.5.批量导入文档

案例需求:利用BulkRequest批量将数据库数据导入到索引库中。

步骤如下:



  • 利用mybatis-plus查询酒店数据




  • 将查询到的酒店数据(Hotel)转换为文档类型数据(HotelDoc)




  • 利用JavaRestClient中的BulkRequest批处理,实现批量新增文档


批量处理BulkRequest,其本质就是将多个普通的CRUD请求组合在一起发送。

其中提供了一个add方法,用来添加其他请求:

编辑


可以看到,能添加的请求包括:



  • IndexRequest,也就是新增




  • UpdateRequest,也就是修改




  • DeleteRequest,也就是删除


其实还是三步走:



  • 1)创建Request对象。这里是BulkRequest




  • 2)准备参数。批处理的参数,就是其它Request对象,这里就是多个IndexRequest




  • 3)发起请求。这里是批处理,调用的方法为client.bulk()方法


在项目的HotelDocumentTest测试类中,编写单元测试:


5.3.6.小结

文档操作的基本步骤:



  • 初始化RestHighLevelClient




  • 创建XxxRequest。XXX是Index、Get、Update、Delete、Bulk




  • 准备参数(Index、Update、Bulk时需要)




  • 发送请求。调用RestHighLevelClient#.xxx()方法,xxx是index、get、update、delete、bulk




  • 解析结果(Get时需要)






分布式搜索引擎Elasticsearch讲解专题(二)的评论 (共 条)

分享到微博请遵守国家法律