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

news2024/11/20 16:34:27

👨‍🎓作者简介:一位大四、研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进行批量查询:
在这里插入图片描述

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

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

相关文章

C++ 数论相关题目 表达整数的奇怪方式(中国剩余定理)

给定 2n 个整数 a1,a2,…,an 和 m1,m2,…,mn &#xff0c;求一个最小的非负整数 x &#xff0c;满足 ∀i∈[1,n],x≡mi(mod ai) 。 输入格式 第 1 行包含整数 n 。 第 2…n1 行&#xff1a;每 i1 行包含两个整数 ai 和 mi &#xff0c;数之间用空格隔开。 输出格式 输出最小…

使用 create-react-app 创建 react 应用

一、创建项目并启动 第一步&#xff1a;全局安装&#xff1a;npm install -g create-react-app 第二步&#xff1a;切换到想创建项目的目录&#xff0c;使用命令create-react-app hello-react 第三步&#xff1a;进入项目目录&#xff0c;cd hello-react 第四步&#xff1a;启…

内部类 --java学习笔记

内部类 是类中的五大成分之一&#xff08;成员变量、方法、构造器、内部类、代码块&#xff09;&#xff0c;如果一个类定义在另一个类的内部&#xff0c;那么这个类就是内部类当一个类的内部包含了一个整体的事务&#xff0c;且这个事务没必要单独设计时&#xff0c;就可以把…

Java面试题:JMM与锁的理论

王有志&#xff0c;一个分享硬核Java技术的互金摸鱼侠 加入Java人的提桶跑路群&#xff1a;共同富裕的Java人 今天是《面霸的自我修养》的第二弹&#xff0c;内容是Java并发编程中关于Java内存模型&#xff08;Java Memory Model&#xff09;和锁的基础理论相关的问题。这两块内…

网工必备工具:不懂它,何谈高手之位?

点开之前&#xff0c;你脑子里闪出来的工具是什么&#xff1f;ping&#xff1f;又或是arp、tracert、route……&#xff1f; 今天要给你分享的是非常经典的Linux网络抓包工具Tcpdump。 它允许用户拦截和显示发送或收到过网络连接到该计算机的TCP/IP和其他数据包。 Tcpdump 适用…

【语录】岁月

中年 写中年&#xff0c;应该是年少励志三千里 踌躇百步无寸功&#xff0c;转眼高堂已白发 儿女蹒跚学堂中&#xff0c;不如意事常八九&#xff0c;可与人言无二三 可是诸位&#xff0c;不用悲伤&#xff0c;稻盛和夫说&#xff0c; 人生并不是一场物质的盛宴&#xff0c;而是…

12.Golang中类的表示与封装

目录 概述类的表示代码结果 类的封装代码结果 结束 概述 Golang中类的表示与封装 类的表示 代码 注释掉的代码&#xff0c;并不能拿来当赋值或获取值来使用。 package mainimport "fmt"// 类大写则代表&#xff0c;可以被其它包使用 type Hero struct {// 属性方法大…

30岁以就业为目标学前端,快歇着吧;反之50岁都不晚。

Hi&#xff0c;我是贝格前端工场&#xff0c;首先声明声明我们不搞前端培训&#xff0c;有很多老铁在留言中问我关于前端学习的问题&#xff0c;最普遍的一个问题就是30岁以后学前端晚了吗&#xff1f;今天借着此篇文章回答一下。 一、30岁学前端的三种人 首先抛开年龄不说&am…

【计算数组连续值的移动距离】及【计算遥控器按键总次数】

计算数组连续值的移动距离及计算遥控器按键总次数 计算数组连续值的移动距离计算遥控器按键总次数 计算数组连续值的移动距离 /*** 计算数组连续值的移动距离* 给定一个乱序的整数数组&#xff0c;数组中值为1~n&#xff0c;请计算出所有数字移动到比其大1的数字位置的距离和。…

【vue2】路由之 Vue Router

文章目录 一、安装二、基础使用1、简单的示例2、动态路由2.1 定义动态路径参数2.2 获取动态路径的参数2.3 捕获所有路由 3、嵌套路由4、编程式的导航4.1 router.push4.2 router.replace4.3 router.go(n) 5、命名路由6、重定向 三、进阶1、导航守卫1.1 全局前置守卫1.2 全局后置…

1Panel CloudFlare证书申请失败的解决方案

在升级1Panel后&#xff0c;使用 CloudFlare DNS验证时&#xff0c;会提示 [*.biliwind.com] [*.biliwind.com] acme: error presenting token: cloudflare: failed to find zone biliwind.com.: ListZonesContext command failed: Invalid request headers (6003) 为解决此问…

如何在Arxiv上预发表自己的手稿

1. 使用latex编辑好自己的手稿。可以使用latex软件或者overleaf。尽量避免警告&#xff0c;否则会在上传到arxiv时出现意外的错误。 2. https://arxiv.org/登陆并注册arxiv账号 3. 点击 开始新的提交&#xff08;START NEW SUBMISSION&#xff09; 4. 主要的问题是参考文献的导…

C++:auto 关键字 范围for

目录 auto 关键字&#xff1a; 起源&#xff1a; auto的使用细则&#xff1a; auto不能推导的场景&#xff1a; 范围for&#xff1a; 范围for的使用条件&#xff1a; C的空指针&#xff1a; 注意&#xff1a; auto 关键字&#xff1a; 起源&#xff1a; 随着程序越…

全角色服务、全场景支撑、全业务应用的新一代智慧教室

新一代智慧教室以“数智化助力高质量人才培养”为核心目标&#xff0c;以AI赋能的智能硬件为基础构建多形态智慧教学环境&#xff0c;以中台为支撑实现数据、设备、系统、业务的互联互通、开放共享&#xff0c;以平台全面覆盖教学应用&#xff0c;采集、汇聚、挖掘、分析课前课…

【周赛】第382场周赛

&#x1f525;博客主页&#xff1a; A_SHOWY&#x1f3a5;系列专栏&#xff1a;力扣刷题总结录 数据结构 云计算 数字图像处理 力扣每日一题_ 从这一场&#xff08;第382场周赛&#xff09;周赛开始记录&#xff0c;目标是尽快达到准确快速AC前三道题&#xff0c;每场比赛…

【服务器GPT+MJ+GPTs】创建部署GPT+MJ+GPTs程序网站

目录 🌺【前言】 🌺【准备】 🌺【宝塔搭建GPT+MJ+GPTs】 🌼1. 给服务器添加端口 🌼2. 安装宝塔 🌼3. 安装Docker 🌼4. 安装ChatGPT程序 🌼5. 程序更新 🌼6. 修改端口 | 密码 🌼7. 绑定域名+申请SSL证书 🌺【前言】 相信大家都对openai的产品ch…

【2024】Docker部署Redis

1.说明&#xff1a; 因为容器实例的运行是有生命周期的&#xff0c;一些redis的备份、日志和配置文件什么的最好还是放在服务器本地。这样当容器删除时&#xff0c;我们也可以保留备份和日志文件。所以先在本地服务器安装redis并配置文件设置。下面是安装步骤: 2.安装步骤 1…

Unity 命令模式(实例详解)

文章目录 示例1&#xff1a;基础命令类结构示例2&#xff1a;旋转对象命令示例3&#xff1a;增加道具命令示例4&#xff1a;切换场景命令示例5&#xff1a;播放音效命令 在Unity中使用命令模式&#xff08;Command Pattern&#xff09;是一种常见的设计模式&#xff0c;用于实现…

LeetCode344反转字符串(java实现)

今天我们来分享的题目是leetcode344反转字符串。题目描述如下&#xff1a; 我们观察题目发现&#xff0c;题目要求使用O(1)的空间解决这一问题。那么我们就不能进行使用开辟新的数组进行反转了。 解题思路&#xff1a;那么该题的我得思路是使用双指针的方法进行题解&#xff0…

深度强化学习(王树森)笔记01

深度强化学习&#xff08;DRL&#xff09; 本文是学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。本文在ChatGPT辅助下完成。 参考链接 Deep Reinforcement Learning官方链接&#xff1a;https://github.com/wangshusen/DRL 源代码链接&#xff1a;https://github.c…