2023-02-09 - 3 Java客户端的使用

news2024/11/24 4:37:30

1 Java客户端的使用

为了演示RestHighLevelClient的使用,需要创建一个Spring Boot Web项目。该项目的依赖配置如下:

<dependencies>     
        <!--Spring Boot Web依赖--> 
        <dependency> 
            <groupId>org.springframework.boot</groupId> 
            <artifactId>spring-boot-starter-web</artifactId> 
        </dependency> 
        <!--ES客户端依赖--> 
        <dependency> 
            <groupId>org.elasticsearch.client</groupId> 
            <artifactId>elasticsearch-rest-high-level-client</artifactId> 
            <version>7.10.2</version> 
        </dependency> 
        <!--ES依赖--> 
        <dependency> 
            <groupId>org.elasticsearch</groupId> 
            <artifactId>elasticsearch</artifactId> 
            <version>7.10.2</version> 
        </dependency> 
        <!--使用Lombok简化开发--> 
        <dependency> 
            <groupId>org.projectlombok</groupId> 
            <artifactId>lombok</artifactId> 
        </dependency> 
</dependencies>

在application.yml文件中配置ES的连接信息如下:

server:
  port: 8888

elasticsearch:
  rest:
    hosts: 127.0.0.1:9200
    username: elastic
    password: password

如上所示,hosts、username和password需要分别填写协调节点服务地址(IP地址+端口号)、用户名、密码。当有多个协调节点时,可以设置hosts值为多个协调节点服务地址,中间用逗号分隔。

下面的代码定义了类EsClient,方法initSimpleClient()返回一个RestHighLevelClient并注册到Spring Boot中。

package com.inspur.elasticsearch.client;

import cn.hutool.core.util.StrUtil;
import lombok.val;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Objects;

/**
 * es客户端
 *
 * 为生成RestHighLevelClient的实例,这里使用EsClient类注册Bean到Spring Boot的方式。
 * RestHighLevelClient的构造方法接受一个RestClientBuilder实例,而调用RestClient.builder()方法可以生成RestClientBuilder实例。
 * RestClient.builder()方法需要传递一个Http Host对象或者HttpHost数组。
 * HttpHost是Apache lib库中对HTTP请求进行封装的一种方法,其构造方法接收主机地址、端口和请求协议3个参数。
 * 当有多个协调节点时,需要读取配置文件的参数构造HttpHost数组。
 *
 * @author zhaoshuai-lc
 * @date 2023/02/09
 */
@Component
public class EsClient {
    @Value("${elasticsearch.rest.hosts}")
    private String hosts;

    @Bean
    public RestHighLevelClient initSimpleClient() {
        HttpHost[] httpHosts = Arrays.stream(hosts.split(StrUtil.COMMA)).map(host -> {
            val hostParts = host.split(StrUtil.COLON);
            val hostName = hostParts[0];
            val port = Integer.parseInt(hostParts[1]);
            return new HttpHost(hostName, port, HttpHost.DEFAULT_SCHEME_NAME);
        }).filter(Objects::nonNull).toArray(HttpHost[]::new);
        // 构建客户端
        return new RestHighLevelClient(RestClient.builder(httpHosts));
    }
}

下面定义Service。前面已经在Spring Boot中注册了RestHighLevelClient,在Service中就可以使用RestHighLevelClient成员变量了。Service的简要定义如下:

package com.inspur.elasticsearch.service;

import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * es服务
 *
 * @author zhaoshuai-lc
 * @date 2023/02/09
 */
@Service
public class EsService {
    @Autowired
    private RestHighLevelClient client;

}

这样就创建了高级的REST客户端。

2 Java带验证客户端的使用

在生产环境下,ES一般都会开启安全验证功能,由于ES Java客户端使用的也是HTTP标准规范中的认证机制,因此在建立客户端和服务端的连接时需要一组凭证用于鉴定用户身份,而这组凭证就是用户名和密码。

CredentialsProvider类是一个凭证类,通过CredentialsProvider.setCredentials()方法可以设置凭证。UsernamePasswordCredentials类可以用明文的形式来表示认证凭证,通过CredentialsProvider.setCredentials()方法设置它的实例,就可以完成凭证的构建。

当使用RestClient.builder()方法构建完RestClientBuilder实例后,需要调用RestClient Builder.setHttpClientConfigCallback()方法完成认证。RestClientBuilder.setHttpClientConfig Callback()方法需要传入一个RestClientBuilder.HttpClientConfigCallback实例,构造完该实例后,可以在该实例的customizeHttpClient()方法中传输之前创建的凭证。下面是带验证的客户端的创建过程:

package com.inspur.elasticsearch.client;

import lombok.val;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Objects;

@Component
public class EsCredentialsClient {
    @Value("${elasticsearch.rest.hosts}")               //读取ES主机+端口配置
    private String hosts;
    @Value("${elasticsearch.rest.username}")            //读取ES用户名
    private String esUser;
    @Value("${elasticsearch.rest.password}")            //读取ES密码
    private String esPassword;

    @Bean
    public RestHighLevelClient initClient() {
        //根据配置文件配置HttpHost数组
        HttpHost[] httpHosts = Arrays.stream(hosts.split(",")).map(
                host -> {
                    //分隔ES服务器的IP和端口
                    val hostParts = host.split(":");
                    val hostName = hostParts[0];
                    val port = Integer.parseInt(hostParts[1]);
                    return new HttpHost(hostName, port, HttpHost.DEFAULT_SCHEME_NAME);
                }).filter(Objects::nonNull).toArray(HttpHost[]::new);
        // CredentialsProvider类是一个凭证类,通过CredentialsProvider.setCredentials()方法可以设置凭证
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        // 通过CredentialsProvider.setCredentials()方法设置它的实例,就可以完成凭证的构建
        credentialsProvider.setCredentials(AuthScope.ANY,
                // UsernamePasswordCredentials类可以用明文的形式来表示认证凭证
                new UsernamePasswordCredentials(esUser, esPassword));
        //返回带验证的客户端
        return new RestHighLevelClient(
                // 使用RestClient.builder()方法构建完RestClientBuilder实例
                RestClient.builder(httpHosts)
                        // 调用RestClientBuilder.setHttpClientConfigCallback()方法完成认证
                        // 传入一个HttpClientConfigCallback实例
                        .setHttpClientConfigCallback(httpClientBuilder -> {
                            // 构造完该实例后,可以在该实例的customizeHttpClient()方法中传输之前创建的凭证
                            httpClientBuilder.disableAuthCaching();
                            return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                        }));
    }
}

3 Java客户端搜索文档

就像在介绍Kibana一样,我们还是构建一个请求来学习搜索功能。使用Java客户端API构造一个搜索请求,该请求在hotel索引中按照title字段搜索“再来”。为方便进行结果展示,首先封装一个酒店的POJO类:

package com.inspur.elasticsearch.pojo;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 酒店实体类
 *
 * @author zhaoshuai-lc
 * @date 2023/02/09
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Hotel {
    /**
     * id
     */
    private String id;
    /**
     * 索引
     */
    private String index;
    /**
     * 分数
     */
    private Float score;

    /**
     * 标题
     */
    private String title;
    /**
     * 城市
     */
    private String city;
    /**
     * 价格
     */
    private Double price;
}

package com.inspur.elasticsearch.service;

import com.google.common.collect.Lists;
import com.inspur.elasticsearch.pojo.Hotel;
import lombok.val;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.List;

/**
 * es服务
 *
 * @author zhaoshuai-lc
 * @date 2023/02/09
 */
@Service
public class EsService {
    @Qualifier("initSimpleClient")
    @Autowired
    private RestHighLevelClient client;

    /**
     * 根据标题获得酒店
     *
     * @param keyword 关键字
     * @return {@link List}<{@link Hotel}>
     */
    public List<Hotel> getHotelFromTitle(String keyword) {
        val request = new SearchRequest("hotel");
        val builder = new SearchSourceBuilder();
        // 构建query
        val query = QueryBuilders.matchQuery("title", keyword);
        builder.query(query);
        request.source(builder);
        List<Hotel> hotelList = Lists.newArrayList();
        try {
            val searchResponse = client.search(request, RequestOptions.DEFAULT);
            val status = searchResponse.status();
            if (!RestStatus.OK.equals(status)) {
                return null;
            }
            SearchHits hits = searchResponse.getHits();
            for (SearchHit hit : hits) {
                val hotel = new Hotel();
                hotel.setId(hit.getId());
                hotel.setIndex(hit.getIndex());
                hotel.setScore(hit.getScore());

                val dataMap = hit.getSourceAsMap();
                val title = String.valueOf(dataMap.get("title"));
                hotel.setTitle(title);
                val city = String.valueOf(dataMap.get("city"));
                hotel.setCity(city);
                val price = Double.parseDouble(String.valueOf(dataMap.get("price")));
                hotel.setPrice(price);
                hotelList.add(hotel);
            }
            return hotelList;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}

    @GetMapping(value = "/getRec")
    public String getRec(@RequestParam String keyword) {
        val hotelList = esService.getHotelFromTitle(keyword);
        if (CollectionUtil.isNotEmpty(hotelList)) {
            return hotelList.toString();
        }
        return "no data .";
    }

在这里插入图片描述

4 Spring Boot客户端简介

Spring Data Elasticsearch是Spring Boot套件中的一个组件,在Spring Boot中连接ES可以使用Spring Data Elasticsearch。Spring Data Elasticsearch是Spring Data项目的一部分,该项目致力于提供一致的基于Spring的数据查询和存储编程模型。Spring Data Elasticsearch封装了创建客户端的逻辑并与服务端保持长连接,让我们不必关注于网络连接问题。并且,通过对Repository接口的自动实现,Spring Data Elasticsearch可以直接通过方法名的语义实现查询功能,如常见的findBy+字段名+操作。此外,Spring Data Elasticsearch还具有OR-Mapping功能,即查询到数据后,可以将数据直接封装到自定义的POJO中,方便后续对数据进行加工处理。

4.1创建Spring Boot客户端

为了演示Spring Data Elasticsearch客户端的使用,需要创建一个Spring Boot Web项目。该项目的依赖配置如下:

<dependencies>
    <!-- Spring Boot Web依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--Spring Data Elasticsearch依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>
    <!--使用Lombok简化开发-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

在application.yml文件中,需要配置ES的连接信息:

spring:
  elasticsearch:
    rest:
      uris: http://localhost:9200
      username: elastic
      password: password

其中,uris、username和password项需要填写协调节点服务地址(IP地址+端口号)、用户名和密码。当有多个协调节点时,可以设置uris的值为多个协调节点的服务地址,中间用逗号分隔。至此,当项目启动时Spring Data Elasticsearch就会创建客户端,然后连接ES服务端并与其保持长连接。

4.2 Spring Boot客户端搜索文档

本节使用之前的搜索示例,即按照标题搜索包含“再来”的酒店。首先封装一个酒店的POJO类:

package com.inspur.elasticsearch.pojo;

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;

@Data
@Document(indexName = "hotel")
public class Hotel_ {
    /**
     * 在ID字段中添加了一个注解@Id。
     * 注意,一个Spring Data Elasticsearch的POJO必须定义一个被@Id修饰的字段,它是和索引中的_id相对应的。
     * 当搜索完成时,Spring Data Elasticsearch会将该POJO的字段填充为搜索结果显示的数据,包括ID字段(填充为文档的_id值)。
     */
    @Id
    private String id;
    private String title;
    private String city;
    private String price;
}

下面介绍EsRepository。这个EsRepository定义为接口,它需要继承CrudRepository接口。在EsRepository接口中,可以按照业务需求定义方法,Spring Data Elasticsearch会自动找到其类库中合适的实现类。EsRepository的定义代码如下:

package com.inspur.elasticsearch.pojo;

import org.springframework.data.repository.CrudRepository;

import java.util.List;

public interface EsRepository extends CrudRepository<Hotel_, String> {
    List<Hotel_> findByTitleLike(String title);
}

在EsRepository中定义了findByTitleLike()方法,Spring Data Elasticsearch会自动根据方法名称识别出方法的具体逻辑,然后生成Bean并填充逻辑代码实现该方法。

完成EsRepository的定义后,在Service中就可以定义EsRepository类型的成员变量了,由Spring Boot完成注入,在getHotelFromTitle()方法中调用EsRepository的对应方法完成搜索。

package com.inspur.elasticsearch.service;
/**
 * es服务
 *
 * @author zhaoshuai-lc
 * @date 2023/02/09
 */
@Service
public class EsService {
    @Autowired
    private EsRepository esRepository;
    public List<Hotel_> getHote_LFromTitle(String keyword) {
        return esRepository.findByTitleLike(keyword);
    }

}

下面介绍Controller的实现部分,URL还是只映射到/test。在Controller中,使用EsService搜索到结果以后直接将其打印到网页上。TestController的实现代码如下:

    @GetMapping(value = "/getRec_")
    public String getRec_(@RequestParam String keyword) {
        val hote_lFromTitle = esService.getHote_LFromTitle(keyword);
        if (CollectionUtil.isNotEmpty(hote_lFromTitle)) {
            return hote_lFromTitle.toString();
        }
        return "no data .";
    }

在这里插入图片描述

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

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

相关文章

tcp的理解

1、源端口号&#xff1a;发送方端口号2、目的端口号&#xff1a;接收方端口号3、序列号&#xff1a;报文段的数据的第一个字节的序号3、确认序号&#xff1a;期望收到对方下一个报文段的第一个数据字节的序号4、首部长度(数据偏移)&#xff1a;TCP报文段的数据起始距离TCP报文段…

List、ArrayList与顺序表的介绍(数据结构系列3)

目录 前言&#xff1a; 1.List 1.1什么是List 1.2List的使用 2.ArrayList 2.1线性表 2.2ArrayList的方法 2.3ArrayList的模拟实现 2.4ArrayList的使用 2.5ArrayList的三种遍历方式 2.5.1for循环遍历 2.5.2for-each遍历 2.5.3使用迭代器遍历 结束语&#xff1a; 前…

分享88个JS焦点图代码,总有一款适合您

分享88个JS焦点图代码&#xff0c;总有一款适合您 88个JS焦点图代码下载链接&#xff1a;https://pan.baidu.com/s/1zfspX9OSsbAlL53fjiSCEw?pwdulz6 提取码&#xff1a;ulz6 Python采集代码下载链接&#xff1a;https://wwgn.lanzoul.com/iKGwb0kye3wj base_url "…

XGBoost

目录 1.XGBoost推导示意图 2.分裂节点算法 Weighted Quantile Sketch 3.对缺失值得处理 1.XGBoost推导示意图 XGBoost有两个很不错得典型算法&#xff0c;分别是用来进行分裂节点选择和缺失值处理 2.分裂节点算法 Weighted Quantile Sketch 对于特征切点点得选择&#xff…

怎么不让消息弹出?录屏弹窗怎么关

当我们对电脑屏幕进行录制时&#xff0c;时不时跳出的消息窗口和广告会影响我们录制的效果。怎样不让消息弹出&#xff1f;如何关闭录屏弹窗&#xff1f;使用“锁定窗口录制”模式&#xff0c;就能很好地解决这个问题。那有没有拥有“锁定窗口”录制模式的录屏工具&#xff1f;…

synchronized 关键字-监视器锁 monitor lock

1.代码示例&#xff1a; package thread3;import java.util.Scanner;public class Test2 {public static Object object new Object();public static void main(String[] args) throws InterruptedException {Thread thread1 new Thread(() -> {Scanner scanner new Sca…

盂县基本情况

寒假的活动报告&#xff0c;万物皆可CSDN&#xff0c;贴一下吧 盂县隶属于阳泉市&#xff0c;阳泉市是李彦宏和刘慈欣的家乡&#xff0c;阳泉市内有百度云计算中心 基本情况 盂县&#xff0c;隶属山西省阳泉市&#xff0c;地处山西省东部、太行山西麓&#xff0c;东与河北省平…

测试开发面经

操作系统 进程与线程 进程间通信方式 进程间的六种通信方式 管道消息队列共享内存信号量信号套接字 socket长连接和短连接 长连接与短连接的概念&#xff1a;前者是整个通讯过程&#xff0c;客户端和服务端只用一个Socket对象&#xff0c;长期保持Socket的连接&#xff1b…

Windows/VM虚拟机安装黑群晖6.1-----保证有效而且简单操作

1视频&#xff1a;Windows/VM虚拟机安装黑群晖教程_哔哩哔哩_bilibili2:网址&#xff1a;Synology Web Assistant3&#xff1a;重新打开群晖操作步骤1&#xff1a;按着视频下载好资源后&#xff0c;按照视频操作&#xff0c;途中修改地方&#xff08;两个情况选择其中一个&…

Docker系列(镜像原理)03

前言 镜像就是图中的集装箱&#xff0c;仓库就是超级码头&#xff0c;容器就是我们运行程序的地方。 从联合文件系统说起 Union文件系统(UnionFS )是一种分层、轻量级并且高性能的文件系统。它支持对文件系统的修改作为一次提交来一层层的叠加&#xff0c;同时可以将不同目录…

【游戏逆向】】游戏全屏捡物的分析实现

前言 在角色对战类中&#xff0c;拾取怪物掉落的装备是一项必备的工作&#xff0c;由于装备位置掉落的不确定性&#xff0c;玩家想要拾取离角色距离较远的装备需要一定的时间&#xff0c;这一段时间往往会影响游戏的评分或是玩家的心态&#xff0c;基于此&#xff0c;全屏捡物…

【Unity VR开发】结合VRTK4.0:键盘操作运动与旋转

前言&#xff1a; 当我们的手柄无发进行VR测试&#xff0c;或者想通过键盘进行验证&#xff0c;那么就用到了我们今天的一个功能&#xff1a;组合操作。组合操作允许更复杂的输入类型&#xff0c;我们将介绍如何使用布尔输入&#xff08;如键盘键&#xff09;来模拟模拟轴&…

Java中LinkedList增删改比ArrayList快吗?

在 Java 中&#xff0c;LinkedList 和 ArrayList 的性能是不同的&#xff0c;具体取决于你所需要的操作。 对于频繁的插入和删除操作&#xff0c;LinkedList 的性能通常更好&#xff0c;因为它使用了链表数据结构&#xff0c;只需更改节点的指针就可以在链表中插入或删除元素。…

剑指Offer 第26天 表示数值的字符串 Hard

表示数值的字符串_牛客题霸_牛客网 描述 请实现一个函数用来判断字符串str是否表示数值&#xff08;包括科学计数法的数字&#xff0c;小数和整数&#xff09;。 科学计数法的数字(按顺序&#xff09;可以分成以下几个部分: 1.若干空格 2.一个整数或者小数 3.&#xff08;可选&…

计算机组成原理第七章笔记记录

仅仅作为笔记记录,B站视频链接&#xff0c;若有错误请指出&#xff0c;谢谢 基本概念 演变过程 I/O系统基本组成 I/O软件 包括驱动程序、用户程序、管理程序、升级补丁等 下面的两种方式是用来实现CPU和I/O设备的信息交换的 I/O指令 CPU指令的一部分,由操作码,命令码,设备…

前端 基于 vue-simple-uploader 实现大文件断点续传和分片上传

文章目录一、前言二、后端部分新建Maven 项目后端pom.xml配置文件 application.ymlHttpStatus.javaAjaxResult.javaCommonConstant.javaWebConfig.javaCheckChunkVO.javaBackChunk.javaBackFileList.javaBackChunkMapper.javaBackFileListMapper.javaBackFileListMapper.xmlBac…

2023年rabbitMq面试题汇总4(7道)

一、如何保证消息的顺序性&#xff1f;1. 通过某种算法&#xff0c;将需要保持先后顺序的消息放到同⼀个消息队列中(kafka中就是partition,rabbitMq中就是queue)。然后只⽤⼀个消费者去消费该队列。2. 可以在消息体内添加全局有序标识来实现。二、使⽤RabbitMQ增加rest服务吞吐…

JVM调优几款好用的内存分析工具

对于高并发访问量的电商、物联网、金融、社交等系统来说&#xff0c;JVM内存优化是非常有必要的&#xff0c;可以提高系统的吞吐量和性能。通常调优的首选方式是减少FGC次数或者FGC时间&#xff0c;以避免系统过多地暂停。FGC达到理想值后&#xff0c;比如一天或者两天触发一次…

【Android -- 每日一问】现在 Android 怎么学?学什么?

不管在任何行业&#xff0c;任何岗位&#xff0c;初级技术人才总是供大于求&#xff1b;不管任何行业、岗位&#xff0c;技术过硬的也都是非常吃香的&#xff01; 这几年 Android 新技术的迭代明显加速了&#xff0c;有来自外部跨平台新物种的冲击&#xff0c;有去 Java 化的商…

Dropout的原理与细节?

1. 什么是Dropout? Dropout是通过使得每个神经元以一定的概率停止工作来接缓解过拟合问题。dropout(随机失活):dropout是通过遍历神经网络每一层的节点,然后通过对该层的神经网络设置一个keep_prob(节点保留概率),即该层的节点有keep_prob的概率被保留,keep_prob的取值范围…