• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

2. Elasticsearch客户端

武飞扬头像
小白不很白
帮助1

搭建ES项目、使用java代码。可选的客户端有RestHighLevelClient、Spring Data Elasticsearch和Jest,本章将用一个搜索需求分别进行介绍。

1.1 Kibana客户端简介

Kibana是ELK家族中一个开源、免费的可视化数据搜索和分析平台。借助Kibana,用户不需要编码就可以将ES中分析的结果进行可视化呈现,如以常用的饼图、柱状图和时序图等方式呈现。除了可视化数据分析功能,Kibana还提供了Dev Tools,它是一款可以与ES进行交互式请求的工具,可以借助它进行DSL调试。限于篇幅,本节只介绍Kibana搭配单机版ES的配置方法

1.2 Kibana安装

注意:最好保持和es版本一致。

下载地址https://www.elastic.co/cn/downloads/kibana 版本直接下载:https://artifacts.elastic.co/downloads/kibana/kibana-7.10.2-windows-x86_64.zip

  1. 下载完成直接解压
  2. 修改kibana文件夹下config/kibana.yml 把es的访问地址给写上 elasticsearch.hosts: [“http://localhost:9200”]
  3. 访问地址 http:127.0.0.1:5601
  4. 点击Dev Tools 目前的工具包含
    1. Console:提供ES Rest形式交互的控制台
    2. Search Profiler:可以分析ES响应某一请求的耗时
    3. GROK DeBugger:提供GROK语言的调试器,联合使用logstash上传数据时,用作调试分割文本的表达式
    4. Painless Lab:提供Painless语言的调试器,用户在自定义排序脚本代码时可以使用

学新通

  1. 通过Kibana客户查询数据
    1. 学新通

2. Java客户端简介

ES 和客户端的通信是根据Http来通信的。用户可以通过任意语言来进行通信。例如:java、Python等。java语言已经支持了很多的API只要拿来使用即可。

2.1 创建SpringBoot项目 导入es相关联的jar包

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.7-SNAPSHOT</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.xiaobai</groupId>
    <artifactId>es</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>es</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <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>
<!--        springBoot-data-Es 依赖-->
<!--        <dependency>-->
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>-->
<!--        </dependency>-->




        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

学新通

2.2 application.yml

elasticsearch:
  rest:
    hosts: 127.0.0.1:9200

2.3 创建ES client端Bean

  1. 无安全验证玩法
package com.example.xiaobai.es.resthightlevel;

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.context.annotation.Configuration;

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

@Configuration
public class EsClient {


    @Value("${elasticsearch.rest.hosts:}")         //读取ES主机 端口配置
    private String hosts;

    @Bean(value = "restHighLevelClient")
    public RestHighLevelClient initSimpleClient() {
        //根据配置文件配置HttpHost数组
        HttpHost[] httpHosts = Arrays.stream(hosts.split(",")).map(
                host -> {
                    //分隔ES服务器的IP和端口
                    String[] hostParts = host.split(":");
                    String hostName = hostParts[0];
                    int 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));
    }
}
学新通
  1. 有安全验证玩法(生产)
@Bean(value = "restHighLevelClient")
    public RestHighLevelClient initSimpleClient1() {
        //根据配置文件配置HttpHost数组
        HttpHost[] httpHosts = Arrays.stream(hosts.split(",")).map(
                host -> {
                    //分隔ES服务器的IP和端口
                    String[] hostParts = host.split(":");
                    String hostName = hostParts[0];
                    int port = Integer.parseInt(hostParts[1]);
                    return new HttpHost(hostName, port, HttpHost.DEFAULT_SCHEME_NAME);
                }).filter(Objects::nonNull).toArray(HttpHost[]::new);

        // 生成凭证
        final BasicCredentialsProvider basicCredentialsProvider = new BasicCredentialsProvider();
        basicCredentialsProvider.setCredentials(AuthScope.ANY,new UsernamePasswordCredentials(esUser,esPassword));
        //构建客户端
        return new RestHighLevelClient(RestClient.builder(httpHosts).setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
            @Override
            public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpAsyncClientBuilder) {
                return httpAsyncClientBuilder.setDefaultCredentialsProvider(basicCredentialsProvider);
            }
        }));
    }
学新通

2.4 创建创建酒店对象pojo

package com.xiaobai.es.pojo;

import lombok.Data;

@Data
    public class Hotel {

        /**
* 对应文档id
*/
        private String id;

        /**
* 索引名称
*/
        private String index;

        /**
* 分数
*/
        private Float score;

        /**
* 酒店 名称
*/
        private String title;

        /**
* 酒店城市
*/
        private String city;

        /**
* 酒店价格
*/
        private Double price;

    }

学新通

2.5 创建service类

package com.xiaobai.es.service;

import com.xiaobai.es.pojo.Hotel;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
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.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class EsService {

    @Resource
    private RestHighLevelClient restHighLevelClient;

    private final static String INDEX_NAME = "hoteld";

    public List<Hotel> getHotelFromTitle(String keyword){
        // 客户端请求 创建请求对象 传入索引名称
        SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
        // 构建查询条件对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 书写查询语句
        searchSourceBuilder.query(QueryBuilders.matchQuery("title",keyword));
        // 把查询语句设置给请求对象
        searchRequest.source(searchSourceBuilder);

        List<Hotel> hotels = new ArrayList<>();
        // 查询
        try {
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            RestStatus status = searchResponse.status();
            if (status != RestStatus.OK){
                return hotels;
            }
            SearchHits hits = searchResponse.getHits();
            for (SearchHit hit : hits) {
                Hotel hotel = new Hotel();
                hotel.setId(hit.getId());
                hotel.setIndex(hit.getIndex());
                hotel.setScore(hit.getScore());
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                hotel.setTitle((String) sourceAsMap.get("title"));
                hotel.setCity((String) sourceAsMap.get("city"));
                hotel.setPrice((Double) sourceAsMap.get("price"));
                hotels.add(hotel);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return hotels;
    }
}

学新通
  1. 首先创建SearchRequest对象 传入要查询的索引名称hoteld。
  2. 创建承载的查询条件对象SearchSourceBuilder
    1. 传入QueryBuilder对象传入查询条件对象。本次是根据九点名称来模糊查询。
  3. 请求对象设置查询条件对象。 searchRequest.source(searchSourceBuilder);
  4. 通过restHighLevelClient查询。
    1. SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    2. searchResponse.getHits() 返回了所有查询结果的封装数据。
    3. 遍历Hits 可得到Hit。这里面可以获取到对应的索引名称、分数、文档id等
    4. hit.getSourceAsMap()把文档内容转换成map的方式便于获取。但是可能会有null指针的情况。

2.6 elasticsearch-rest-high-level-client

  1. 这种方式配置起来比较复杂。
  2. 每次查询的时候都是根据rest http的方式去调用es服务。每次都需要建立链接
  3. 查询信息和转换数据比较麻烦

3. Spring-Data-Elasticsearch 方式

spring-data-elasticsearch是和springBoot中的一套组件。可以和es服务保持长链接,不需要每次查询的时候需要建立网络链接了。并且可以通过Repository接口自动实现,可以通过方法名的语义实现查询功能。而且查询到数据后可以直接封装到自定义pojo中。方便后续对数据的二次加工。

3.1 创建SpringBoot客户端

3.1.1导入相关jar包

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.8</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.sping.data</groupId>
    <artifactId>springdata</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springdata</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

学新通

3.1.2 配置application.yml

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

如果想要配置多个节点只需要uris 配置多个ip即可。中间用逗号分割。

3.1.3 使用spring-data-elasticsearchl来根据"再来"查询符合的酒店

3.1.3.1创建pojo类
@Data
@Document(indexName = "hoteld")
public class Hotel1 {

    @Id
    private String id;

    private String title;

    private String city;

    private Double price;
}

@Id 代表是主键id 级文档id

3.1.3.2 创建Repository对象

/**
 * @author liruiqing
 */
public interface EsRepository extends CrudRepository<Hotel1,String> {

    /**
     * 根据 title 查询符合的酒店
     * @param title
     * @return
     */
    List<Hotel1> findByTitleLike(String title);
}

以方法名语义的方式实现查询数据。
需要继承CrudRepository<o1,o2> o1 为pojo类 o2为文档id类型

3.1.3.3 service类

@Service
public class EsService {

    @Autowired
    private EsRepository esRepository;

    public List<Hotel1> findByTitleLike(String keyword){
        List<Hotel1> byTitleLike = esRepository.findByTitleLike(keyword);
        return byTitleLike;
    }
}

3.1.3.4 controller类

@RestController
public class TestController {

    @Autowired
    private EsService esService;

    @RequestMapping("/test")
    public String getHotelStr(){
        List<Hotel1> hotels = esService.findByTitleLike("再来");
        if (hotels.isEmpty()){
            return "no data";
        }
        return hotels.toString();
    }
}

4. Jest客户端搜索文档

Jest是为springBoot项目是低版本时做兼容时用到的,如果SpringBoot的版本过高的话application.yml中配置信息已经不生效了,被移除了。下面的版本是可以使用的。

4.1 配置项

4.1.1 导入相关jar包
<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.1.8.RELEASE</version>
  <relativePath/> <!-- lookup parent from repository springboot版本-->
</parent>

<properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

            <!--Jest依赖-->
            <dependency>
                <groupId>io.searchbox</groupId>
                <artifactId>jest</artifactId>
                <version>6.3.1</version>
            </dependency>
            <!--简化开发组件Lombok-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
            <!--ES依赖-->
            <dependency>
                <groupId>org.elasticsearch</groupId>
                <artifactId>elasticsearch</artifactId>
                <version>7.10.2</version>
            </dependency>



        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>co.elastic.clients</groupId>
            <artifactId>elasticsearch-java</artifactId>
            <version>7.17.8</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

学新通
4.1.2 配置application.yml
spring:
  elasticsearch:
    jest:
      uris: http://127.0.0.1:9200
      username: elastic
      password: password
server:
  port: 8082

4.2 实现

4.2.1 Pojo类
@Data
public class Hotel {

    @JestId // 文档id
    private String id;

    private String title;

    private String city;

    private Double price;
}
4.2.2 service类
@Service
public class EsService {

    @Resource
    private JestClient jestClient;

    public List<Hotel> findByTitleLike(String keyword){

        // 创建sql语句对象 本次为查询语句
        MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("title", keyword);

        // 设置查询builder对象 并把查询对象设置进去
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(matchQuery);

        // 调用search.Builder把查询的builder对象字符串给设置进去 addIndex是索引名称
        Search search = new Search.Builder(searchSourceBuilder.toString()).addIndex("hoteld").build();

        try {
            // 使用jestClient.execute()方法获取searchResult数据对象 并把返回的数据集通过getSourceAsObjectList转换为集合 
            SearchResult searchResult = jestClient.execute(search);
            if (searchResult.isSucceeded()){
                List<Hotel> sourceAsObjectList = searchResult.getSourceAsObjectList(Hotel.class);
                return sourceAsObjectList;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
学新通
4.2.3 Controller类
@RestController
public class TestController {

    @Autowired
    private EsService esService;

    @RequestMapping("/test")
    public String findByTitleLike(){
        List<Hotel> hotels = esService.findByTitleLike("再来");
        if (hotels == null || hotels.isEmpty()){
            return "no data";
        }
        return hotels.toString();
    }

}

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgjihaf
系列文章
更多 icon
同类精品
更多 icon
继续加载