SpringCloud系列(十五)[分布式搜索引擎篇] - 结合实际应用场景学习并使用 RestClient 客户端 API

news2024/9/23 5:18:10

前面的文章具体介绍了是索引库及文档的一些基本操作指令, 指令还是挺简单的; 那么实际应用场景下, 我们是如何操作 ElasticSearch 的呢?
 其实 ElasticSearch 官方已经为我们提供了各种不同语言的客户端, 目的就是为了来操作 ElasticSearch, 这些客户端的本质就是组装 DSL 语句, 通过 http 请求发送给 ElasticSearch, ➽官方文档地址.
在这里插入图片描述

RestClient

  • ❶ RestClient 的初始化操作
    • 1.1 Mapping 映射分析
    • 1.2 初始化 RestClient
    • 1.3 创建索引库
    • 1.3 删除索引库
    • 1.4 查询索引库 (判断索引库是否存在)
    • 1.4 总结
  • ❷ RestClient 文档操作
  • 2.1 新增文档
    • 2.2 查询文档
    • 2.3 删除文档
    • 2.4 修改文档
  • 3 批量数据导入

❶ RestClient 的初始化操作

本文数据将借用某站的酒店数据库数据, 主要学习 RestClient 的含义及如何使用.

1.1 Mapping 映射分析

  关于索引库前面的博客已经说过最关键的是 mapping 映射, 因为 mapping 里面就是索引库的结构, 字段及子字段都在 properties 中, 主要注意下面几点:

  • 字段名和字段数据类型可以参照数据库表中的表结构名称和类型;
  • 根据业务来分析是否要参与搜索, 如图片地址就不需要参与搜索;
  • 根据内容来判断是否需要分词, 如果内容就是一个整体则无需分词;
  • 分词器根据业务来选择 ik_max_word 或者 ik_smart.

1.2 初始化 RestClient

  关于 RestClient 的初始化主要分为三步, 首先要做的是对 RestHighLevelClient 类的初始化, 建立与 ElasticSearch 的连接 (因为与 ElasticSearch 的一切交互都封装到了这个类中).

⅓: 引入 RestHighLevelClient 依赖

        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.17.7</version>
        </dependency>

⅔: 检查自己的 SpringBoot 默认的 ElasticSearch 版本是哪个, 如果不是 7.17.7, 就要改成 7.17.7
在这里插入图片描述
1: 初始化 RestHighLevelClient

@Bean
    public RestHighLevelClient client() {
        return new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://172.16.**.**:9200")
        ));
    }

1.3 创建索引库

针对索引库的操作在测试类中使用; 关于索引库的创建也是分为三步:
Ⅰ: 创建 Request 对象, CreateIndexRequest create = new CreateIndexRequest(“hotel”);
Ⅱ: 添加请求参数, 这里的参数就是 DSL 中 JSON 参数部分, 因为字符串比较长, 可以定义一个静态字符串常量;
Ⅲ: 发送请求, client.indices() 方法的返回值是 IndicesClient 类型, 封装了所有与索引库操作有关的方法.

@Test
    void createHotelIndex() throws IOException {
        CreateIndexRequest request = new CreateIndexRequest("hotel");
        request.source(MAPPING_TEMPLATE, XContentType.JSON);
        client.indices().create(request, RequestOptions.DEFAULT);
    }
// 静态字符串常量 MAPPING_TEMPLATE
public static final String MAPPING_TEMPLATE = "{\n" +
            "  \"mappings\": {\n" +
            "    \"properties\": {\n" +
            "      \"id\": {\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"name\": {\n" +
            "        \"type\": \"text\",\n" +
            "        \"analyzer\": \"ik_max_word\"\n" +
            "      },\n" +
            "      \"address\": {\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"index\": false\n" +
            "      },\n" +
            "      \"price\": {\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"score\": {\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"brand\": {\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"city\": {\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"starName\": {\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"business\": {\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"location\": {\n" +
            "        \"type\": \"geo_point\"\n" +
            "      },\n" +
            "      \"pic\": {\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"index\": false\n" +
            "      },\n" +
            "      \"all\": {\n" +
            "        \"type\": \"text\",\n" +
            "        \"analyzer\": \"ik_max_word\"\n" +
            "      }\n" +
            "    }\n" +
            "  }\n" +
            "}";
}

在这里插入图片描述


1.3 删除索引库

  上篇博客可以看的出来删除索引库的 DSL 语句比较简单, DELETE /索引库名, 与 创建索引库相比只不过是由 PUT 变成了 DELETE, 请求路径无需改变, 也没有任何请求参数. 当然代码还是分三步走:
Ⅰ: 创建 Request 对象, 注意这次不再是 CreateIndexRequest create 对象, 而是 DeleteIndexRequest 对象;
Ⅱ: 准备参数, 当然这里无参数;
Ⅲ: 发送请求, 改成了 delete 方法; client.indices() 方法的返回值是 IndicesClient 类型, 封装了所有与索引库操作有关的方法.

@Test
    void testDeleteHotelIndex() throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest("hotel");
        client.indices().delete(request, RequestOptions.DEFAULT);
    }


1.4 查询索引库 (判断索引库是否存在)

查询索引库操作对应的 DSL 语句是 GET /索引库名 ;
Ⅰ: 创建 Request 对象, 这次是 GetIndexRequest 对象;
Ⅱ: 准备参数, 当然这里也是无参数;
Ⅲ: 发送请求, 改成了 exists 方法; client.indices() 方法的返回值是 IndicesClient 类型, 封装了所有与索引库操作有关的方法.

@Test
    void testExistsHotelIndex() throws IOException {
        GetIndexRequest request = new GetIndexRequest("hotel");
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        System.err.println(exists ? "索引库已经存在!" : "索引库不存在!");
    }

在这里插入图片描述

1.4 总结

通过上面的创建 / 删除 / 查询 操作可以看得出来, JavaRestClient 的步骤和 ElasticSearch 的流程基本相似, 核心都在 client.indices() 这个方法上, 索引库的基本步骤如下:

  • 初始化 RestHighLevelClient;
  • 创建各自的 Request;
  • 准备 DSL, 只有创建的时候需要用到, 查询删除都用不到;
  • 发送请求, 调用 client.indices() 这个方法.

❷ RestClient 文档操作

关于 RestClient 文档的操作也是要参照已经写好的 DSL 语句, 操作并不是很难; 但是前提是要确定好自己的数据库的实体类, 其次还要定义一个新的实体类, 这个实体类要与索引库的结构吻合 (我这里的数据还是用的某站酒店的数据).

2.1 新增文档

关于文档的新增也是分为三步走, 先是创建 Request 对象, 然后准备请求的参数, 也就是 DSL 中的数据, 最后发送请求即可.

@Test
    void testAddDocument() throws IOException {
        Hotel hotel = hotelService.getById(1);
        HotelDoc hotelDoc = new HotelDoc(hotel);

        IndexRequest request = new IndexRequest("hotel").id(hotel.getId().toString());
        request.source(JSON.toJSONString(hotelDoc), XContentType.JSON);
        client.index(request, RequestOptions.DEFAULT);
    }

在这里插入图片描述

我们从数据库中获取到的数据需要先查询出来, 得到数据对象, 然后需要转换为 HotelDoc 对象 (因为要与索引库的结构一致), 然后再序列化为 json 格式;

具体流程步骤:

  • 根据 id 查询到产品数据;
  • 将查询到的数据对象封装成 Doc 类型 (要与索引库的结构一致);
  • 将 Doc 数据序列化为 JSON 格式;
  • 创建 IndexRequest ,指定索引库的名称及 id;
  • 准备请求参数, 也就是刚才已经转换的 JSON 文档;
  • 发送请求, 注意这里不再是 client.indeces()了.

2.2 查询文档

查询文档比较简单, 只需要准备 Request 对象, 然后发送请求即可; 这里还是要注意, 查询到的是 JSON 文档, 因此需要将 JSON 数据进行解析.

@Test
    void testGetDocumentById() throws IOException {
        GetRequest request = new GetRequest("hotel","61083");
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        String json = response.getSourceAsString();

        HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
        System.out.println(hotelDoc);
    }

在这里插入图片描述

具体步骤:

  • 准备 GetRequest 对象;
  • 发送请求, client.get() 进行请求, 得到的是 json 格式;
  • 解析结果, 也就是将 json 文档进行反序列化.

2.3 删除文档

删除文档和查询文档基本类似, 只是将 get 改成了 delete;

@Test
    void testDeleteDocument() throws IOException {
        DeleteRequest request = new DeleteRequest("hotel", "1");
        client.delete(request, RequestOptions.DEFAULT);
    }

在这里插入图片描述
具体步骤:

  • 准备 DeleteRequest 对象, 指定索引库的名字及 id;
  • 发送请求, 使用 client.delete() 方法.

2.4 修改文档

关于文档的修改前面的文章已经说过有两种方法, 全量修改和增量修改;

  • 全量修改: 本质是先根据 id 删除, 然后再新增;
  • 增量修改: 就是直接修改文档中指定的字段值;
  • 当然在 RestClient 的 API 中, 是根据 id 是否存在来进行判断, 如果存在就修改, 不存在就新增.
@Test
    void testUpdateDocument() throws IOException {
        UpdateRequest request = new UpdateRequest("hotel", "1");
        request.doc(
                "name", "Remake",
                "age", "999"
        );
        client.update(request, RequestOptions.DEFAULT);
    }

在这里插入图片描述
具体步骤:

  • 准备 Request 对象, 修改用的是 UpdateRequest;
  • 准备参数, 也就是 JSON 文档, 里面包含了所要修改的字段;
  • 更新文档, 调用 client.update() 方法.

3 批量数据导入

批量数据的导入用到了 BulkRequest, 具体步骤和新增基本一致, 先查询到数据库中的数据, 然后转换为 Doc 文档数据, 利用 BulkRequest 进行批处理, 实现批量数据的新增文档.
批量数据的新增其实质就是将多个 CRUD 请求组合在一起进行发送, 其中提供了一个 add 方法, 用来添加其他的请求, 其他的请求就包含了新增, 修改和删除操作.

@Test
    void testBulkRequest() throws IOException {
        List<Hotel> hotels = hotelService.list();
        
        BulkRequest request = new BulkRequest();
        for (Hotel hotel : hotels) {
            HotelDoc hotelDoc = new HotelDoc(hotel);
            request.add(new IndexRequest("hotel")
                    .id(hotelDoc.getId().toString())
                    .source(JSON.toJSONString(hotelDoc), XContentType.JSON));
        }
        client.bulk(request, RequestOptions.DEFAULT);
    }

具体步骤:

  • 从数据库中查到批量数据;
  • 创建 Request 请求, 用到了 BulkRequest;
  • 准备参数, 添加多个新增的 Request, 这里也要转换为 Doc 文档 (要与索引库的结构一致) 格式;
  • 发送请求.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/392607.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vmware虚拟机与树莓派4B安装ubuntu1804 + ros遇到的问题

如题所示&#xff0c;本人在虚拟机上安装ubuntu1804&#xff0c;可以很容易安装&#xff0c;并且更换系统apt源和ros源&#xff0c;然后安装ros&#xff0c;非常顺利&#xff0c;但是在树莓派4B上安装raspiberry系统就遇到了好多问题。 树莓派我烧录的是这个镜像&#xff1a;ub…

ASO优化之选择最佳关键词

ASO的关键字排名是指针对特定的关键词在应用商店搜索结果中所形成的位置。虽然这看起来很简单&#xff0c;但应用商店排名不仅仅是位置&#xff0c;应用的排名统计数据都要考虑进去。 应用商店搜索结果因国家/地区而异&#xff0c;这就意味着如果我们从不同的国家或地区进行搜…

经典文献阅读之--Lifelong SLAM(变化环境中Lifelong定位建图)

0. 简介 商场、超市等大多数现实场景的环境随时都在变化。不考虑这些变化的预建地图很容易变得过时。因此&#xff0c;有必要拥有一个最新的环境模型&#xff0c;以促进机器人的长期运行。为此《A General Framework for Lifelong Localization and Mapping in Changing Envir…

Oracle技术分享 exp导数据时报错ORA-01578 ORA-01110

问题描述&#xff1a;exp导数据时报错ORA-01578 ORA-01110&#xff0c;如下所示&#xff1a; 数据库&#xff1a;oracle 19.12 多租户 1、异常重现 [oracledbserver ~]$ exp ora1/ora1orclpdbfileemp.dmp tablesemp logexp.log Export: Release 19.0.0.0.0 - Production onS…

OpenEuler20.03源码安装配置PostgreSQL13.4详细图文版

OpenEuler安装配置PostgreSQL 序号更新内容更新日期更新人1完成第一至三章内容编辑&#xff1b;2021年9月18日liupp2增加PostgreSQL服务开机自动启动&#xff1b;2021年10月25日liupp 一、准备条件 OpenEuler(Hyper-V虚拟机)&#xff1a; 版本&#xff1a;20.03 LTS SP2下载地…

推荐几个超实用的开源自动化测试框架

有什么好的开源自动化测试框架可以推荐&#xff1f;为了让大家看文章不蒙圈&#xff0c;文章我将围绕3个方面来阐述&#xff1a; 1、通用自动化测试框架介绍 2、Java语言下的自动化测试框架 3、Python语言下的自动化测试框架 随着计算机技术人员的大量增加&#xff0c;通过编写…

什么是MyBatis?无论是基础教学还是技术精进,你都应该看这篇MyBatis

文章目录学习之前&#xff0c;跟你们说点事情&#xff0c;有助于你能快速看完文章一、先应用再学习&#xff0c;代码示例1. 第一个MyBatis程序2. MyBatis整合Spring3. SpringBoot整合MyBatis二、MyBatis整体流程&#xff0c;各组件的作用域和生命周期三、说说MyBatis-config.xm…

流域土壤保持及GIS实现

流域土壤保持及GIS实现 流域水土过程模拟与生态调控 01 土壤保持模拟 土壤侵蚀不仅会引起耕地生产力下降、河床抬升、泥沙淤积阻塞河道等生态环境问题&#xff0c;也会对人们正常的生产生活产生威胁。生态系统的土壤保持量&#xff08;吨/公顷/年&#xff09;&#xff0c;是…

$3 : 水​​​​​项目实战 - 水果库存系统

javase知识点复习&#xff1a; final关键字&#xff1a;http://t.csdn.cn/bvFgu 接口的定义&#xff0c;特性&#xff0c;实现&#xff0c;继承&#xff1a;http://t.csdn.cn/tbXl3 异常&#xff1a;http://t.csdn.cn/VlS0Z DAO的概念和角色&#xff08;设计理念&#xff09;&a…

适配PyTorch FX,OneFlow让量化感知训练更简单

作者 | 刘耀辉审稿 | BBuf、许啸宇1背景近年来&#xff0c;量化感知训练是一个较为热点的问题&#xff0c;可以大大优化量化后训练造成精度损失的问题&#xff0c;使得训练过程更加高效。Torch.fx在这一问题上走在了前列&#xff0c;使用纯Python语言实现了对于Torch.nn.Module…

学习笔记:Java并发编程(补)CompletableFuture

学习视频&#xff1a;https://www.bilibili.com/video/BV1ar4y1x727 参考书籍&#xff1a;《实战 JAVA 高并发程序设计》 葛一鸣 著 系列目录 学习笔记&#xff1a;Java 并发编程①_基础知识入门学习笔记&#xff1a;Java 并发编程②_共享模型之管程学习笔记&#xff1a;Java 并…

win10开机黑屏只有鼠标怎么办?这里有4个妙招

真实案例&#xff1a;电脑开机黑屏&#xff0c;只出现鼠标箭头光标怎么办&#xff1f; “早上打开电脑&#xff0c;发现开不了机&#xff0c;屏幕上只有一个鼠标光标&#xff01;百度搜索了很长时间&#xff0c;但所有的方法都没有奏效。求教各位大神&#xff0c;有什么好方法…

中电金信源启小程序开发平台 赋能金融+业务生态共享共建

导语&#xff1a;源启小程序开发平台立足于“为金融业定制”&#xff0c;从小程序全生命周期的角度出发&#xff0c;助力银行、互联网金融、保险、证券客户实现一站式小程序开发、发布、运营与营销。企业可以通过源启小程序开发平台&#xff0c;低成本高效率开发一款定制化小程…

The 19th Zhejiang Provincial Collegiate Programming Contest vp

和队友冲了这场&#xff0c;极限6题&#xff0c;重罚时铁首怎么说&#xff0c;前面的A题我贡献了太多的罚时&#xff0c;然后我的G题最短路调了一万年&#xff0c;因为太久没写了&#xff0c;甚至把队列打成了优先队列&#xff0c;没把head数组清空完全&#xff0c;都是我的锅呜…

搭载英伟达Jetson Orin的Allspark 2全新亮相,算力高达100TOPS!

Allspark 2 系列AI边缘计算机 Allspark 2经过设计优化的铝合金外壳&#xff0c;内置静音涡轮风扇&#xff0c;散热优秀。尺寸102.5X62.5X31mm&#xff0c;整机重量188g。 相比Allspark 1&#xff0c;2代整机轻了25克&#xff0c;更加轻薄。 在机身更加轻薄的情况下&#xff0c…

1497. 树的遍历

文章目录1.二叉树的遍历2.二叉树的构造3.例题3.1不使用BFS3.2使用BFS二叉树的构造&#xff1a;没有中序遍历则无法唯一构造1.二叉树的遍历 2.二叉树的构造 3.例题 一个二叉树&#xff0c;树中每个节点的权值互不相同。 现在给出它的后序遍历和中序遍历&#xff0c;请你输出它…

蓝桥杯训练day2

day21.二分(1)789. 数的范围(2)四平方和&#xff08;1&#xff09;哈希表做法&#xff08;2&#xff09;二分做法(3)1227. 分巧克力&#xff08;4&#xff09;113. 特殊排序(5)1460. 我在哪&#xff1f;2.双指针(1)1238. 日志统计(2)1240. 完全二叉树的权值&#xff08;3&#…

koa-vue的分页实现

1.引言 最近确实体会到了前端找工作的难处&#xff0c;不过大家还是要稳住心态&#xff0c;毕竟有一些前端大神说的有道理&#xff0c;前端发展了近20年&#xff0c;诞生了很多leader级别的大神&#xff0c;这些大神可能都没有合适的坑位&#xff0c;我们新手入坑自然难一些&am…

HD-G2L-IOT V2.0核心板MPU压力测试

1. 测试对象HD-G2L-IOT基于HD-G2L-CORE V2.0工业级核心板设计&#xff0c;双路千兆网口、双路CAN-bus、2路RS-232、2路RS-485、DSI、LCD、4G/5G、WiFi、CSI摄像头接口等&#xff0c;接口丰富&#xff0c;适用于工业现场应用需求&#xff0c;亦方便用户评估核心板及CPU的性能。H…

PMP高分上岸人士的备考心得,分享考试中你还不知道的小秘密

上岸其实也不是什么特别难的事情&#xff0c;考试一共就180道选择题&#xff0c;题目只要答对60.57%就可以通过考试&#xff0c;高分通过没在怕的&#xff0c;加油备考呀朋友们&#xff01; 这里也提一嘴&#xff0c;大家备考的时候比较顾虑的一个问题就是考试究竟要不要报班…