实用篇-ES-RestClient操作文档

news2024/11/19 1:45:59

一、RestClient案例准备

对es概念不熟悉的话,先去看上面的 '实用篇-ES-索引库和文档',不建议基础不牢就直接往下学

ES官方提供了各种不同语言的客户端,用来操作ES。这些客户端的本质就是组装DSL语句,通过http请求来发送给ES。

官方文档地址: https://www.elastic.co/guide/en/elasticsearch/client/index.html

下面就使用java程序进行操作es,不再像上面那样使用浏览器页面进行操作es

在下面会逐步完成一个案例: 下载提供的hotel-demo.zip压缩包,解压后是hotel-demo文件夹,是一个java项目工程文件,按照条件创建索引库,索引库名为hotel,mapping属性根据数据库结构定义。还要下载一个tb_hotel.sql文件,作为数据库数据

hotel-demo.zip下载:https://cowtransfer.com/s/36ac0a9f9d9043
tb_hotel.sql下载: https://cowtransfer.com/s/716f049850a849

第一步: 把tb_hotel.sql文件导入进你的数据库

第二步:idea打开解压后的文件

第三步:在application.yml中配置正确的信息

二、hotel数据结构分析

在es中,mapping要考虑的问题: 字段名、数据类型、是否参与搜索、是否分词、如果分词那么分词器是什么。

我们刚刚在mysql导入了tb_hotel.sql,里面有很多数据,我们需要基于这些数据结构,去分析并尝试编写对应的es的mapping映射

先看mysql中的数据类型(已有),如下

根据mysql的数据类型等信息,编写es(没有,自己对着上面的sql写的)。注意经纬度在es里面是geo_point类型,且经纬度是写在一起的

PUT /hotel
{
  "mappings": {
    "properties": {
      "id":{
        "type": "keyword"
      },
      "name":{
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "address":{
        "type": "keyword",
        "index":false
      },
      "price":{
        "type": "integer"
      },
      "score":{
        "type": "integer"
      },
      "brand":{
        "type": "keyword"
      },
       "city":{
        "type": "keyword"
      },
       "starName":{
        "type": "keyword"
      },
       "business":{
        "type": "keyword"
      },
       "location":{
        "type": "geo_point"
      },
      "pic":{
        "type":"keyword",
        "index": false
      }
    }
  }
}

可以看到name,brand,score,city,starName等字段都要参与搜索,也就是用户可能根据多个关键字搜,查询条件是多个值,这时候可以用es提供的copy_to属性,把这些字段都拷贝到这个字段中,就可以实现在一个字段中搜到多个字段的内容了

下面演示把名字(name)、品牌(brand)和商圈(business)三个字段拷贝到all字段,代码如下

PUT /hotel
{
  "mappings": {
    "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"
      },
       "starName":{
        "type": "keyword"
      },
       "business":{
        "type": "keyword",
        "copy_to": "all"
      },
       "location":{
        "type": "geo_point"
      },
      "pic":{
        "type":"keyword",
        "index": false
      },
      "all":{
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}

三、初始化RestClient

操作主要是在idea的hotel-demo项目进行,hotel-demo项目(不是springcloud项目,只是springboot项目)是前面 '1. RestClient案例准备',跳过的可回去补

第一步: 在hotel-demo项目的pom.xml添加如下

<properties>
        <java.version>1.8</java.version>
        <elasticsearch.version>7.12.1</elasticsearch.version>
</properties>

<!--引入es的RestHighLevelClient,版本要跟你Centos7里面部署的es版本一致-->
<dependency>
	<groupId>org.elasticsearch.client</groupId>
	<artifactId>elasticsearch-rest-high-level-client</artifactId>
	<version>7.12.1</version>
</dependency>

第二步: 在hotel-demo项目的src/test/java/cn.itcast.hotel目录新建HotelIndexTest类,写入如下

package cn.itcast.hotel;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.IOException;

public class HotelIndexTest {

     private RestHighLevelClient client;

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

     @BeforeEach
     void setUp(){
          this.client = new RestHighLevelClient(RestClient.builder(
                  //指定你Centos7部署的es的主机地址
                  HttpHost.create("http://192.168.229.129:9200")
          ));
     }

     @AfterEach
     void tearDown() throws IOException {
          this.client.close();
     }

}

运行init方法,可以看到client的信息打印出来,表示初始化成功 

四、创建索引库

不是通过kibana的浏览器控制台,通过DSL语句来进行操作es,在es里面创建索引库

而是通过上一节初始化的RestClient对象,在Java里面去操作es,创建es的索引库。根本不需要kibana做中间者

第一步: 在src/main/java/cn.itcast.hotel目录新建constants.HotelConstants类,里面写DSL语句,如下

其中长长的字符串就是我们在前面 '2. hotel数据结构分析' 里面写的。忘了怎么写出来的,可以回去看看

package cn.itcast.hotel.constants;

public class HotelConstants {
     public static final String MAPPING_TAMPLATE = "{\n" +
             "  \"mappings\": {\n" +
             "    \"properties\": {\n" +
             "      \"id\":{\n" +
             "        \"type\": \"keyword\"\n" +
             "      },\n" +
             "      \"name\":{\n" +
             "        \"type\": \"text\",\n" +
             "        \"analyzer\": \"ik_max_word\",\n" +
             "        \"copy_to\": \"all\"\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" +
             "}";
}

第二步: 在hotel-demo项目的HotelIndexTest类,添加如下

   @Test
     void testCreateHotelIndex() throws IOException {
          //创建Request对象
          CreateIndexRequest request = new CreateIndexRequest("hotel");
          //请求参数,MAPPING_TEMPLATE是静态常量字符串,内容是创建索引库的DSL语句
          request.source(HotelConstants.MAPPING_TEMPLATE, XContentType.JSON);
          //发起请求
          client.indices().create(request, RequestOptions.DEFAULT);
     }

第三步: 确保下面的服务你都在Centos7里面启动了

systemctl start docker # 启动docker服务
docker restart es #启动elasticsearch容器
docker restart kibana #启动kibana容器

第四步: 验证。运行HotelIndexTest类的testCreateHotelIndex测试方法

第五步: 验证,浏览器打开http://192.168.229.129:5601

五、删除和判断索引库

1、删除索引库。在hotel-demo项目的HotelIndexTest类,添加如下。然后运行testDeleteHotelIndex方法

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

 

2. 判断索引库是否存在,刚才我们已经运行过删除索引库了,现在我们来写一个测试来判断索引库是否存在

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

六、新增文档

案例: 去数据库查询酒店数据,把查询到的结果导入到hotel索引库(上一节我们已经创建一个名为hotel的索引库),实现酒店数据的增删改查

简单说就是先去数据查酒店数据,把结果转换成索引库所需要的格式(新增文档的DSL语法)然后写到索引库,然后在索引库对这些酒店数据进行增删改查

第一步:在HotelIndexTest写入如下

package cn.itcast.hotel;

import cn.itcast.hotel.constants.HotelConstants;
import cn.itcast.hotel.pojo.Hotel;
import cn.itcast.hotel.pojo.HotelDoc;
import cn.itcast.hotel.service.IHotelService;
import com.alibaba.fastjson.JSON;
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;

@SpringBootTest
public class HotelIndexTest {

     private RestHighLevelClient client;

     @Autowired
     private IHotelService hotelService;

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

     @Test
     void testCreateHotelIndex() throws IOException {
          //创建Request对象
          CreateIndexRequest request = new CreateIndexRequest("hotel");
          //请求参数,MAPPING_TEMPLATE是静态常量字符串,内容是创建索引库的DSL语句
          request.source(HotelConstants.MAPPING_TEMPLATE, XContentType.JSON);
          //发起请求
          client.indices().create(request, RequestOptions.DEFAULT);
     }

     @Test
     void testDeleteHotelIndex() 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.err.println(exists?"索引库存在":"索引库不存在");
     }


     @BeforeEach
     void setUp(){
          this.client = new RestHighLevelClient(RestClient.builder(
                  //指定你Centos7部署的es的主机地址
                  HttpHost.create("http://192.168.229.129:9200")
          ));
     }

     @AfterEach
     void tearDown() throws IOException {
          this.client.close();
     }

     @Test
     void testAddDocument() throws IOException {
          //根据id查询酒店数据
          //注意数据库中bigint类型对应java中的long类型
          Hotel hotel = hotelService.getById(60223L);
          //转换为文档类型
          HotelDoc hotelDoc = new HotelDoc(hotel);
          //准备Request对象
          IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString());
          //准备Json文档
          request.source(JSON.toJSONString(hotelDoc),XContentType.JSON);
          //发送请求
          client.index(request,RequestOptions.DEFAULT);
     }

}

主要是新增这个方法 

@Test
     void testAddDocument() throws IOException {
          //根据id查询酒店数据
          //注意数据库中bigint类型对应java中的long类型
          Hotel hotel = hotelService.getById(60223L);
          //转换为文档类型
          HotelDoc hotelDoc = new HotelDoc(hotel);
          //准备Request对象
          IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString());
          //准备Json文档
          request.source(JSON.toJSONString(hotelDoc),XContentType.JSON);
          //发送请求
          client.index(request,RequestOptions.DEFAULT);
     }

第二步:文档新增成功,我们去浏览器查询一下 

七、查询文档

不管我们学习什么样的文档操作,java中的代码和DSL中的语句非常相似,所以我们可以类比着DSL语句来编写java代码

具体操作如下,我们查询刚才添加的id为60223的文档信息

 @Test
     void testGetDocumentById() throws IOException {
          //创建request对象
          GetRequest request = new GetRequest("hotel","60223");
          //发送请求
          GetResponse response = client.get(request,RequestOptions.DEFAULT);
          //解析结果
          String res = response.getSourceAsString();
          System.out.println(res);
     }

八、更新文档

具体操作,把id为60223的文档信息更新一下,名字和城市

第一步:写入此方法,并运行 

 @Test
     void testUpdateDocumentById() throws IOException {
          //创建Request对象
          UpdateRequest request = new UpdateRequest("hotel","60223");
          //准备参数,每两个参数为一对key value
          request.doc(
                  "name","上海梅赛德斯奔驰文化中心",
                  "city","阿布扎比"
          );
          //更新文档
          client.update(request,RequestOptions.DEFAULT);
     }

第二步:测试是否更新,在浏览器中Get请求

 九、删除文档

经过以上类比,我们不难写出删除文档的代码

具体操作,删除id为60223的文档信息

@Test
     void testDeleteDocumentById() throws IOException {
          //创建Request对象
          DeleteRequest request = new DeleteRequest("hotel","60223");
          //删除文档
          client.delete(request,RequestOptions.DEFAULT);
     }

 测试如下

十、批量导入文档

我们一直都是操作一条id为60223的文档(相当于数据库表的某一行)。我们如何把mysql的更多数据导入进es的索引库(相当于mysql的表)呢,下面就来学习批量把文档导入进索引库

思路:
1、利用mybatis-plus把MySQL中的酒店数据查询出来
2、将查询到的酒店数据转换为文档类型的数据
3、利用RestClient中bulk批处理方法,实现批量新增文档

第一步: 在HotelDocumentTest类,添加如下

@Test
     void testBulkRequest() throws IOException {
          //mp查出数据库中所有的信息
          List<Hotel> hotelList = hotelService.list();
          //转化为hotelDoc
          List<HotelDoc> hotelDocList = hotelList.stream()
                  .map(new Function<Hotel, HotelDoc>() {
                       @Override
                       public HotelDoc apply(Hotel hotel) {
                            HotelDoc hotelDoc = new HotelDoc(hotel);
                            return hotelDoc;
                       }
                  }).collect(Collectors.toList());
          //创建Bulk请求
          BulkRequest bulkRequest = new BulkRequest();
          hotelDocList.forEach(hotelDoc -> bulkRequest
                          .add(new IndexRequest("hotel").id(hotelDoc.getId().toString())
                          .source(JSON.toJSONString(hotelDoc),XContentType.JSON)));
          //发送bulk请求
          client.bulk(bulkRequest, RequestOptions.DEFAULT);
     }
}

第二步:浏览器批量查询

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

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

相关文章

zabbix的服务器端 server端安装部署

zabbix的服务器端 server 主机iplocalhost&#xff08;centos 7&#xff09;192.168.10.128 zabbix官网部署教程 但是不全&#xff0c;建议搭配这篇文章一起看 zabbixAgent部署 安装mysql 所有配置信息和Zabbix收集到的数据都被存储在数据库中。 下载对应的yum源 yum ins…

openGauss Summit 2023 | Call for Sponsor、Speaker、Demo

数据库作为千行万业数据的基石&#xff0c;也是推动数字经济发展的核心。随着数字经济的蓬勃发展&#xff0c;数据库将迎来更加广阔的应用场景和更加迫切的需求。openGauss 社区旨在汇聚产、学、研、用多方力量&#xff0c;聚焦基础软件核心能力的构建&#xff0c;引领国内数据…

煮蛋器产业研究:全球市场将超过10亿美元

近年来&#xff0c;随着科技的迅猛发展&#xff0c;煮蛋器市场逐渐呈现出多元化和智能化趋势。厂商们不断推出新款煮蛋器&#xff0c;配备更多功能以满足消费者的个性化需求。同时&#xff0c;煮蛋器也受益于烹饪技术的创新&#xff0c;如加热控制和计时功能等的引入&#xff0…

44. Adb调试QT开发的Android程序实用小技巧汇总

1. 说明 使用QT开发Android应用时,如果程序本身出现了问题,很难进行调试。不像在linux或者windows系统中,可以利用QtCreator软件本身进行一些调试,安卓应用一旦在系统中安装后,如果运行中途出现什么BUG,定位问题所在很麻烦。不过,好在有adb这种调试工具可以代替QtCreat…

笔记无法正常展示,小红书笔记收录分析!

很多时候&#xff0c;小红书收录意味着你的流量其实是被记录了&#xff0c;这是有利于你的笔记曝光的一个表现&#xff0c;今天就来带大家一起分享下&#xff0c;为什么笔记无法正常展示&#xff0c;小红书笔记收录分析&#xff01; 一、什么叫小红书笔记收录 不可能所有的笔记…

希尔顿集团旗下酒店为宾客带来冬日活力新玩法

中国上海&#xff0c;2023年11月14日 - 据希尔顿集团发布的《2024年趋势报告》显示&#xff0c;新一代亚洲旅行者正在崛起&#xff0c;也更重视高品质、个性化的服务。希尔顿集团紧随市场脉搏&#xff0c;在即将到来的冬季为宾客精心策划了一系列特色体验&#xff0c;凭借其遍布…

Visual Studio 2019 C# 断点调试代码内存窗口显示无法计算表达式的解决问题

查看如下界面&#xff0c;发现右下角内存1窗口显示无法计算表达式&#xff1a; 按照如下步骤操作即可&#xff1a; 如果s1局部变量此时有值&#xff0c;但是内存窗口还是无法计算表达式我们可以

微同城生活圈小程序源码系统 专业搭建本地生活服务的平台 带完整搭建教程

在互联网的影响下&#xff0c;越来越多的用户开始依赖手机进行日常生活。为了满足本地居民的需求&#xff0c;源码小编来给大家分享一款全新的微同城生活圈小程序源码系统。该系统旨在为本地居民提供一站式的生活服务解决方案&#xff0c;让您的生活更加便捷、高效。 以下是部…

使用 Cloudflare Worker 免费搭建网址导航网站

开源项目 GitHub&#xff1a;https://github.com/sleepwood/CF-Worker-Dir/ CloudFlare Worker&#xff1a;https://workers.cloudflare.com/ 搭建教程 首先&#xff0c;进入cloud flare - Worker 截图20200224180010.png 在 Cloudflare Worker 管理页面创建一个新的 Work…

NCP1654BD65R2G功率因数校正控制器 用于紧凑和坚固的连续导通模式预转换器

NCP1654BD65R2G是一款高效的同步整流控制器&#xff0c;主要用于DC/DC转换器和LED驱动器等应用。该控制器采用了高性能的反馈控制算法&#xff0c;可以实现高达95%以上的转换效率。此外&#xff0c;NCP1654BD65R2G还具有多种保护功能&#xff0c;如过流保护、过热保护、欠压保护…

【Linux】软硬链接和动静态库

软硬链接 软硬链接的区别&#xff1a; **软链接&#xff1a;**是一个独立文件&#xff0c;有自己独立的 inode 和 inode 编号。**硬链接&#xff1a;**不是一个独立的文件&#xff0c;它和目标文件使用的是同一个 inode。硬链接就是单纯的在 Linux 指定的目录下&#xff0c;给…

根据关键词搜索阿里巴巴商品数据列表接口|阿里巴巴商品列表数据接口|阿里巴巴商品API接口|阿里巴巴API接口

阿里巴巴也提供了根据关键词搜索商品数据列表的接口&#xff0c;方便开发者根据关键词搜索商品并进行相关操作。 请求参数可以包括&#xff1a; q&#xff1a;搜索关键字 start_price&#xff1a;开始价格 end_price&#xff1a;结束价格 page&#xff1a;页码 cat&#xff1…

Live800:2023年客服团队管理有哪些思路和方法?

在数字化时代&#xff0c;客服团队成为企业与客户之间的重要桥梁。随着技术不断发展&#xff0c;客服团队管理也在不断进化。到了2023年&#xff0c;最新的客服团队管理将会有哪些思路和方法呢&#xff1f; 一、智能化客服系统 随着人工智能技术的不断发展&#xff0c;智能化客…

超声波清洗机的工作原理是什么样的?值得入手的超声波清洗机推荐

超声波清洗机最常见的应该是在眼镜店了吧&#xff0c;眼镜店用来清洗眼镜频率非常高的&#xff01;超声波清洗机在清洁方面也是非常快速、高效的&#xff01;像眼镜党配戴眼镜脏的第一时间就会想到去眼镜店清洗&#xff0c;但也有很多朋友是随便清洗一下就了事了&#xff0c;其…

大模型的全面回顾,看透大模型 | A Comprehensive Overview of Large Language Models

大模型的全面回顾&#xff1a;A Comprehensive Overview of Large Language Models 返回论文和资料目录 论文地址 1.导读 相比今年4月的中国人民大学发表的大模型综述&#xff0c;这篇综述角度更侧重于大模型的实现&#xff0c;更加硬核&#xff0c;更适合深入了解大模型的一…

运动型蓝牙耳机什么牌子好?市面上热门的运动耳机推荐

​随着生活节奏的加快&#xff0c;越来越多的人开始关注健康和运动。而在运动的时候&#xff0c;佩戴耳机听音乐已经成为了很多人的选择。但是&#xff0c;市面上的运动耳机种类繁多&#xff0c;如何选择一款适合自己的呢&#xff1f;下面&#xff0c;我推荐几款市面上热门的运…

开源社区团购小程序源码系统 商品管理+订单管理+会员管理 带完整搭建教程

社区团购作为一种新型的电商模式&#xff0c;逐渐成为了人们日常生活的一部分。而开源社区团购小程序源码系统&#xff0c;更是受到了广大开发者的热烈欢迎。下面罗峰给大家介绍一款完整的开源社区团购小程序源码系统&#xff0c;包括商品管理、订单管理、会员管理等功能&#…

LCD液晶屏维修日记

有一台显示器不亮了&#xff0c;怀疑是电源接头松了&#xff0c;于是准备自己维修一下&#xff0c;哪知道事情不是这么简单的。于是折腾之路开始了… 拆开液晶显示屏后&#xff0c;发现结构非常高的简单&#xff0c;就两大部分&#xff0c;一个是液晶屏控制板&#xff0c;一个是…

没有设计经验的新手如何制作一本电子画册?

移动信息时代&#xff0c;电子画册逐渐取代纸质画册&#xff0c;它无需印刷&#xff0c;环保节能&#xff0c;也无需随身携带&#xff0c;通过手机/平板/电脑等设备即可随时在线浏览阅读&#xff0c;十分方便。那没有设计经验的新手如何制作一本这样随身携带方便的电子画册呢&a…

基于Qt 多线程(继承 QObject 的线程)

​ 继承 QThread 类是创建线程的一种方法,另一种就是继承QObject 类。继承 QObject 类更加灵活。它通过 QObject::moveToThread()方法,将一个 QObeject的类转移到一个线程里执行。恩,不理解的话,我们下面也画个图捋一下。 通过上面的图不难理解,首先我们写一个类继承 QObj…