详解SpringCloud微服务技术栈:ElasticSearch实践1——RestClient操作索引库与文档

👨‍🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习
🌌上期文章:详解SpringCloud微服务技术栈:ElasticSearch原理精讲、安装、实践
📚订阅专栏:微服务技术全家桶
希望文章对你们有所帮助

在前面已经学习了如何使用DSL语句去操作ElasticSearch的索引库和文档,现在需要用ES官方提供的RestClient,这个客户端本质就是组装DSL语句,通过http请求发送给ES,从而方便我们使用Java代码进行操作。

ElasticSearch实战1——RestClient操作索引库与文档

  • 导入demo
  • hotel数据结构分析
  • RestClient操作索引库
    • 初始化RestClient
    • 创建索引库
    • 删除和判断索引库
  • RestClient操作文档
    • 新增文档
    • 查询文档
    • 更新文档
    • 删除文档
    • 批量导入文档

导入demo

sql文件和项目工程从网盘下,自行导入:

链接:https://pan.baidu.com/s/1CDgGJGvpSu0-s6bFfLWvVA?pwd=nrx2
提取码:nrx2

在这里插入图片描述
在这里插入图片描述

hotel数据结构分析

mapping映射要考虑的问题:字段名、数据类型、是否参与搜索、是否分词、若分词,分词器选什么?
所以,我们需要针对数据库的字段来做mapping映射:
在这里插入图片描述
这里面的信息在做mapping的时候,主要是要会选择是否要参与搜索、是否分词,这需要根据业务需求来实现,比如用户找酒店的时候肯定不会是搜索酒店的地址,因此酒店地址不应该加入搜索,也不应该分词。

需要注意的是,ES中对地理坐标的描述,并不是字符串也不是数字,它支持了2种坐标数据类型:

geo_point:由维度latitude和精度longitude确定的一个点
geo_shape:有多个geo_point组成的复杂几何图形

容易发现,里面有很多字段存在ES中,将来都要参与搜索,也就意味着当用户输入某个字段的时候需要根据这多个字段来搜,效率肯定不高。
而ES提供了一个功能,能够实现多字段搜索同时效率还高的,即字段拷贝。也就是使用copy_to属性将当前字段拷贝到指定字段,示例:

"all":{
	"type": "text",
	"analyzer": "ik_max_word"
}
"brand":{
	"type": "keyword",
	"copy_to": "all"
}

这样我们就可以把需要搜索的字段全部联合到all里面,即可实现用户输入一个信息,多字段搜索,且效率是会大大提高的。
因此在dev tools中编写DSL代码:

# 酒店索引库及mapping映射
PUT /hotel
{
  "mapping": {
    "properties": {
      "id":{
        "type": "keyword"
      },
      "name":{
        "type": "text",
        "analyzer": "ik_max_word",
        "copy_to": "all"
      },
      "address":{
        "type": "keyword",
        "index": false
      },
      "price":{
        "type": "integer"
      },
      "score":{
        "type": "integer"
      },
      "brand":{
        "type": "keyword",
        "copy_to": "all"
      },
      "city":{
        "type": "keyword"
      },
      "startName":{
        "type": "keyword"
      },
      "business":{
        "type": "keyword",
        "copy_to": "all"
      },
      "location":{
        "type": "geo_point"
      },
      "pic":{
        "type": "keyword",
        "index": false
      },
      "all":{
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}

上面代码没有正式执行,用来做个基础样式,最终创建索引库还是要用ES的java客户端来实现,方便之后简化开发。

RestClient操作索引库

初始化RestClient

1、引入ES的RestHighLevelClient依赖:

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

2、SpringBoot默认的ES版本是7.6.2,因此需要覆盖:
在这里插入图片描述

3、初始化RestHighLevelClient:

public class HotelIndexTest {
    private RestHighLevelClient client;

    @Test
    void testInit() {
        System.out.println(client);
    }

    @BeforeEach //提前完成RestHighLevelClient对象的初始化
    void setUp() {
        this.client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.177.130:9200")
        ));
    }

    @AfterEach //结束后要销毁这个初始化
    void tearDown() throws IOException {
        this.client.close();
    }
}

创建索引库

结合DSL语句会比较好看懂,代码如下:

	@Test
    void createHotelIndex() throws IOException {
        //创建request对象
        CreateIndexRequest request = new CreateIndexRequest("hotel");
        //准备请求的参数,为JSON格式
        request.source(MAPPING_TEMPLATE, XContentType.JSON);
        //发送请求,indices为index复数,可以获得操作索引库的所有对象,默认方式发送
        client.indices().create(request, RequestOptions.DEFAULT);
    }

其中MAPPING_TEMPLATE就是之前的DSL语句,复制过来当作静态常量来存储:
在这里插入图片描述

在DEV TOOLS中输入GET /hotel即可查看是否成功创建:
在这里插入图片描述

删除和判断索引库

其实这个可以自行的去做,也挺容易实现的,毕竟indices已经将所有操作索引库的api都封装好了,按Ctrl+Shift+空格即可查看所有方法。
删除索引库:

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

判断索引库是否存在:

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

RestClient操作文档

写一个小demo,去数据库中查询酒店数据,导入到hotel索引库,从而实现酒店数据的CRUD。
需要先进行JavaRestClient的初始化,在之前有代码了,直接CV一下。
而对于文档的操作,不再需要indices了。

新增文档

这里需要用的方法是index,表示新增文档时候创建倒排索引。

	private RestHighLevelClient client;

    @Resource
    private IHotelService hotelService;
    
	@Test
    void testAddDocument() throws IOException {
        //根据id查询酒店
        Hotel hotel = hotelService.getById(61083L);
        /**
         * Hotel对象中的地理位置是分为经度和纬度分别来存的,但是ES中是用geo_point来存的
         * 因此需要先转换为文档类型HotelDoc
         */
        HotelDoc hotelDoc = new HotelDoc(hotel);
        //准备request对象
        IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString());
        //准备JSON文档,传进去的需要是JSON格式的字符串
        request.source(JSON.toJSONString(hotelDoc), XContentType.JSON);
        //发送请求
        client.index(request, RequestOptions.DEFAULT);
    }

在这里插入图片描述

查询文档

根据id查询到的文档数据是JSON,需要反序列化为java对象:

@Test
    void testGetDocumentById() throws IOException {
        GetRequest request = new GetRequest("hotel", "61083");
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        //source里面是这个hotel的相关数据
        String json = response.getSourceAsString();
        //将json反序列化为java对象
        HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
        System.out.println("hotelDoc = " + hotelDoc);
    }

在这里插入图片描述

更新文档

之前讲解了全量更新和局部更新,这里只演示局部更新:

	@Test
    void testUpdateDocument() throws IOException {
        UpdateRequest request = new UpdateRequest("hotel", "61083");
        request.doc(
                "price", "952",
                "starName", "四钻"
        );
        client.update(request, RequestOptions.DEFAULT);
    }

删除文档

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

再次查询,返回null:
在这里插入图片描述

批量导入文档

之前的新增,都是一次就新增一条数据,现在利用JavaRestClient批量导入酒店数据到ES中。

思路:
1、利用mybatis-plus查询酒店数据
2、将查询到的酒店数据(Hotel)转换为文档类型数据(HotelDoc)
3、利用JavaRestClient中的Bulk批处理,实现批量新增文档

	@Test
    void testBulkRequest() throws IOException {
        //批量查询酒店数据
        List<Hotel> hotels = hotelService.list();
        //创建request
        BulkRequest request = new BulkRequest();
        //将hotels转换成HotelDoc
        for (Hotel hotel : hotels) {
            HotelDoc hotelDoc = new HotelDoc(hotel);
            //准备参数,添加多个新增的request
            request.add(new IndexRequest("hotel")
                    .id(hotelDoc.getId().toString())
                    .source(JSON.toJSONString(hotelDoc), XContentType.JSON)
            );
        }
        //发送请求
        client.bulk(request, RequestOptions.DEFAULT);
    }

在dev tools使用GET /hotel/_search进行批量查询:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

多场景建模:阿里MARIA

Multi-scenario ranking framework with adaptmulti-scenario ranking framework with adaptive feature learning 背景 多模态搜索场景支持用户通过不同模态的Query来表达多样的搜索需求。 拍照搜索&#xff08;Visual Search&#xff09;&#xff1a;实拍图作为query相似商…

05.Elasticsearch应用(五)

Elasticsearch应用&#xff08;五&#xff09; 1.Mapping介绍 Mapping是对索引库中文档的约束&#xff0c;类似于数据表结构&#xff0c;作用如下&#xff1a; 定义索引中的字段的名称定义字段的数据类型&#xff0c;例如字符串&#xff0c;数字&#xff0c;布尔等字段&…

antdesignvue中使用VNode写法

1、使用场景 如图&#xff1a;消息提示框中&#xff0c;将数据中的数据单独一行显示 2、代码 let errorList res.result; //后端返回的数据例&#xff1a; ["1. 数据格式不正确","2. 数据已存在"]if(errorList&&errorList.length!0){this.$notif…

IDE server has started, listening on http://127.0.0.1:61945已解决

看了网上很多网上博主写的&#xff0c;总结出来了两个主要方法&#xff0c;以我的为准&#xff0c;很多博客都是错误的&#xff01; 1.打开微信开发者工具的安全权限 设置-安全设置-服务端口 2.必须把appid改为自己的才能打开微信小程序&#xff0c;只能在mainfest里面改&…

【工具使用-Everything】everything只能搜到文件夹,无法搜到文件

一&#xff0c;问题现象 everything搜索时&#xff0c;只能搜索到文件夹&#xff0c;无法搜索到文件夹下的文件。 二&#xff0c;问题原因 everything搜索设置问题&#xff0c;设置为"文件夹"导致 三&#xff0c;解决方法 将搜索选项设置为“所有”即可&#x…

第3章 接口和API设计

第15条&#xff1a;用前缀避免命名空间冲突 OC没有其他语言那种内置的命名空间机制。因此&#xff0c;我们在起名时要设法避免潜在的命名冲突&#xff0c;否则很容易就重名了。若是发生重名冲突&#xff0c;那么应用程序相应的链接过程就会出错。例如&#xff1a; 错误原因在…

ORBSLAM3 运行流程,以rgbd_tum.cc函数为例进行分析

一、运行 使用的是D435i相机自己录制的数据。 运行命令&#xff1a; ./Examples/RGB-D/rgbd_tum /opt/vslam/ORB_SLAM3_detailed_comments-dense_map_new/Vocabulary/ORBvoc.txt /opt/vslam/ORB_SLAM3_detailed_comments-dense_map_new/Examples/RGB-D/TUM1.yaml /opt/vsl…

Modern C++ std::bind的实现原理

1. 前言 前面写过《std::function从实践到原理》&#xff0c;管中规豹了std::function的一点点原理&#xff0c;不过还有一个与std::function密切相关的函数std::bind, 允许编程者绑定几个参数&#xff0c;本文着重介绍它的实现原理。不介绍一下它&#xff0c;有点吃肉不吃蒜味…

【C++干货基地】C++入门篇:输入输出流 | 缺省函数 | 函数重载(文末送书)

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 引入 哈喽各位铁汁们好啊&#xff0c;我是博主鸽芷咕《C干货基地》是由我的襄阳家乡零食基地有感而发&#xff0c;不知道各位的…

JVM-初始JVM

什么是JVM JVM 全称是 Java Virtual Machine&#xff0c;中文译名 Java虚拟机。JVM 本质上是一个运行在计算机上的程序&#xff0c;他的职责是运行Java字节码文件。 Java源代码执行流程如下&#xff1a; JVM的功能 1 - 解释和运行 2 - 内存管理 3 - 即时编译 解释和运行 解释…

如何配置Tomcat服务环境并实现无公网ip访问本地站点

文章目录 前言1.本地Tomcat网页搭建1.1 Tomcat安装1.2 配置环境变量1.3 环境配置1.4 Tomcat运行测试1.5 Cpolar安装和注册 2.本地网页发布2.1.Cpolar云端设置2.2 Cpolar本地设置 3.公网访问测试4.结语 前言 Tomcat作为一个轻量级的服务器&#xff0c;不仅名字很有趣&#xff0…

重塑网络安全格局:零信任安全架构的崛起与革新

零信任安全架构是一种现代安全模式&#xff0c;其设计原则是“绝不信任&#xff0c;始终验证”。它要求所有设备和用户&#xff0c;无论他们是在组织网络内部还是外部&#xff0c;都必须经过身份验证、授权和定期验证&#xff0c;才能被授予访问权限。简而言之&#xff0c;“零…

(2024,MLLM,扩散,中文数据集扩散预训练,多模态提示引导微调)UNIMO-G:通过多模态条件扩散进行统一图像生成

UNIMO-G: Unified Image Generation through Multimodal Conditional Diffusion 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 1. 摘要 2. 方法 3. 结果 1. 摘要 现有的文本到图像…

GraphQL的力量:简化复杂数据查询

1. GraphQL GraphQL 是一种由 Facebook 开发并于 2015 年公开发布的数据查询和操作语言&#xff0c;也是运行在服务端的运行时&#xff08;runtime&#xff09;用于处理 API 查询的一种规范。不同于传统的 REST API&#xff0c;GraphQL 允许客户端明确指定它们需要哪些数据&am…

java以SSL方式连ES

先做准备工作&#xff0c;浏览器方式访问 ES7.X url https://127.0.0.1:8027 弹出用户名和密码 输入后在浏览器得到 { “name” : “DTCNPEMS04”, “cluster_name” : “cnp-es-cluster”, “cluster_uuid” : “wb0So_FqQBOKqtXnsqofTg”, “version” : { “number” : “7.…

力扣hot100 两数相加 链表 思维

Problem: 2. 两数相加 Code ⏰ 时间复杂度: O ( n ) O(n) O(n) &#x1f30e; 空间复杂度: O ( n ) O(n) O(n) /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.…

prometheus监控RabbitMQ策略

一般用官方的rabbitmq_exporter采取数据即可&#xff0c;然后在普米配置。但如果rabbitmq节点的队列数超过了5000&#xff0c;往往rabbitmq_exporter就会瘫痪&#xff0c;因为rabbitmq_exporter采集的信息太多&#xff0c;尤其是那些队列的细节&#xff0c;所以队列多了&#x…

android camera的使用以及输出的图像格式

一、Camera 1.1、结合SurfaceView实现预览 1.1.1、布局 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-au…

SpringBoot项目多数据源配置与MyBatis拦截器生效问题解析

在日常项目开发中&#xff0c;由于某些原因&#xff0c;一个服务的数据源可能来自不同的库&#xff0c;比如&#xff1a; 对接提供的中间库&#xff0c;需要查询需要的数据同步数据&#xff0c;需要将一个库的数据同步到另一个库&#xff0c;做为同步工具的服务对接第三方系统…

离零售业智能体时代的真正开启还有多远?

AIGC&#xff08;生成式人工智能&#xff09;当道的2023年&#xff0c;将LLM&#xff08;大语言模型&#xff09;的各类生成式能力发挥到淋漓尽致、精彩纷呈的程度。各行各业一边在观望大语言模型不断扩宽的商业运用可能&#xff0c;一边在继续探寻能够不断拓宽企业往纵深发展的…