实用篇-ES-RestClient操作文档

一、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);
     }
}

第二步:浏览器批量查询

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

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

相关文章

Linux_一款好用的查看系统信息的桌面软件_包名hardinfo、软件名system profiler and Benchmark

1、安装软件 对源进行更新&#xff0c;sudo apt update 安装&#xff0c;sudo apt install hardinfo 打开&#xff0c;system profiler and Benchmark 2、查看系统信息 2.1、系统基本信息_操作系统信息、内核版本、处理器等 “Summary”汇总了一些基本信息&#xff1a; 处…

Python万圣节礼物

文章目录 系列文章前言小海龟快速入门万圣节蝙蝠万圣节南瓜头万圣节礼物尾声 系列文章 序号文章目录直达链接1浪漫520表白代码https://want595.blog.csdn.net/article/details/1306668812满屏表白代码https://want595.blog.csdn.net/article/details/1297945183跳动的爱心http…

易基因:综合全基因组DNA甲基化和转录组学分析鉴定调控骨骼肌发育潜在基因 | 研究进展

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 DNA甲基化是骨骼肌发育中关键的表观遗传调控机制。但胚胎鸭骨骼肌发育中负责DNA甲基化的调控因子仍然未知。 2023年10月23日&#xff0c;南京农业大学动物科技学院于敏莉副教授团队在《…

Spring全家桶源码解析--2.6 Spring scope 限制bean的作用范围

文章目录 前言一、Scope是什么&#xff1f;二、Scope使用2.1 单例&#xff1a;2.1.1 单例Bean的特点如下&#xff1a;2.1.2 单例设计模式 与单例bean&#xff1a; 2.2 原型bean&#xff1a;2.2.1 原型Bean的特点&#xff1a;2.2.2 原型Bean的销毁&#xff1a; 2.3 Request bean…

Unity中使用VS常用技巧

文章目录 1、Unity预览代码中文显示乱码解决方案2、VS中格式化代码快捷键 1、Unity预览代码中文显示乱码解决方案 ①打开VS&#xff0c;在 扩展 中找到 管理扩展 打开 ②在 管理扩展面板 联机 中搜索 Force UTF-8(No BOM) &#xff0c;点击下载即可 ③重启VS 如果以前编写的脚…

gpt-4-turbo、gpt-4v、dall-e-3 api实测!

上周GPT大更新&#xff0c;不仅开放了GPT-4-Turbo、GPT-4-Vision等模型api&#xff0c;还发布了GPTs&#xff0c;使得用户能够根据需要定义自己的GPT应用&#xff0c;OpenAI在这波AI革命上又一次震撼世人。 笔者也在上周拿到了几个新模型的api资格&#xff0c;一直盼着可以测试…

C语言题目逻辑实战总结

eg1: 已知有1,2,3,4个数字&#xff0c;能组成多少个互不相同且无重复数字的三位数&#xff1f;都是多少 已知&#xff1a;1&#xff1a;三位数 &#xff0c;2:1-4,3&#xff1a;各不相同&#xff0c; 输出&#xff1a;1&#xff1a;有多少个这样的三位数&#xff0c;2&#xff…

免费内网穿透?让外网能访问到自己的接口springboot,暴露自己的接口给外网

内网穿透&#xff1f;让外网能访问到自己的接口java&#xff0c;暴露自己的接口给外网 内网穿透听着就很吊&#xff0c;不就是把没有备案的服务器暴露出去&#xff0c;给别人访问嘛。 自己免费使用测试的话。 下载一个Cpolar 然后注册一下&#xff0c;进来后&#xff0c;直接…

都dubbo3了,别再用xml了配置dubbo服务了

这里是weihubeats,觉得文章不错可以关注公众号小奏技术&#xff0c;文章首发。拒绝营销号&#xff0c;拒绝标题党 背景 最近项目再准备升级dubbo3,所以打算简单实现一个dubbo3的demo。 来学习一下dubbo dubbo3 dubbo3主要是为了融入云原生打造的 Dubbo 3 提供的核心特性列…

Milvus性能优化提速之道:揭秘优化技巧,避开十大误区,确保数据一致性无忧,轻松实现高性能

Milvus性能优化提速之道&#xff1a;揭秘优化技巧&#xff0c;避开十大误区&#xff0c;确保数据一致性无忧&#xff0c;轻松实现高性能 Milvus 是全球最快的向量数据库&#xff0c;在最新发布的 Milvus 2.2 benchmark中&#xff0c;Milvus 相比之前的版本&#xff0c;取得了 …

竞赛 题目:基于LSTM的预测算法 - 股票预测 天气预测 房价预测

文章目录 0 简介1 基于 Keras 用 LSTM 网络做时间序列预测2 长短记忆网络3 LSTM 网络结构和原理3.1 LSTM核心思想3.2 遗忘门3.3 输入门3.4 输出门 4 基于LSTM的天气预测4.1 数据集4.2 预测示例 5 基于LSTM的股票价格预测5.1 数据集5.2 实现代码 6 lstm 预测航空旅客数目数据集预…

PieCloudDB Database 自研内存管理器 ASanAlloc:为产品质量保驾护航

内存管理是计算机科学中至关重要的一部分&#xff0c;它涉及到操作系统、硬件和软件应用之间的动态交互。有效的内存管理可以确保系统的稳定性和安全性&#xff0c;提高系统运行效率&#xff0c;帮助我们最大限度地利用有效的内存资源&#xff0c;合理分配和回收内存&#xff0…

【Linux】进程替换|exec系列函数

文章目录 一、看一看单进程版的进程替换二、进程替换的原理三、多进程版——验证各种程序替换接口exec系列函数execlexeclpexecvexecvp tipsexecleexecve 四、总结 一、看一看单进程版的进程替换 #include<stdio.h> #include<unistd.h> #include<stdlib.h>i…

Elasticsearch的配置学习笔记

文/朱季谦 Elasticsearch是一个基于Lucene的搜索服务器。它提供一个分布式多用户能力的全文搜索引擎&#xff0c;基于RESTful web接口&#xff0c;Elasticsearch是用Java语言开发的。 关于Elasticsearch系列笔记&#xff0c;主要从Elasticsearch的配置、核心组件、架构设计、使…

跟着 Tubi 同事吃遍全世界

在过去的一年里&#xff0c;Tubi 北京办公室的 Pantry 非常忙&#xff0c;忙于接收 Tubi 同事从全球各地带回的美食。而我们也有幸跟随慷慨的同事们尝遍了大江南北的味道。 细数这 30 多次美食分享&#xff0c;我们发现&#xff0c;大家分享的不仅是食物&#xff0c;还是…… …

第二证券:尾盘选股方法?

股票出资是一种危险较高的出资办法&#xff0c;因而怎样挑选合适的股票成为出资者面临的重要问题之一。尾盘选股办法就是一种常用的战略。尾盘是指股票商场生意时间的究竟一段时间&#xff0c;通常是下午3点到收盘之间。在这段时间里&#xff0c;生意量较大&#xff0c;不坚决性…

在Python中使用sqlite3进行数据持久化操作

目录 引言 一、安装sqlite3模块 二、创建数据库连接 三、创建游标对象 四、执行SQL命令 五、提交更改 六、关闭连接 七、使用参数化查询 八、使用ORM进行数据操作 九、备份和恢复数据库 十、处理大量数据 十一、优化查询性能 十二、处理并发访问 十三、处理数据持…

仿真算法收敛与初值的关系

问题&#xff1a; 当电路中存在大电容时&#xff0c;由于初值设置不合理可能导致的仿真算法不收敛的问题。 解决方法&#xff1a;设置初始节点值。 疑问&#xff1a;Node set和Initial Condition的区别。 [求助] node set 和initial condition有很么区别呢&#xff1f; 注&…

7-4链表去重

题目 给定一个带整数键值的链表 L&#xff0c;你需要把其中绝对值重复的键值结点删掉。即对每个键值 K&#xff0c;只有第一个绝对值等于 K 的结点被保留。同时&#xff0c;所有被删除的结点须被保存在另一个链表上。例如给定 L 为 21→-15→-15→-7→15&#xff0c;你需要输出…