首页 > 其他分享 >SpringBoot整合ES查询

SpringBoot整合ES查询

时间:2022-10-16 12:01:05浏览次数:74  
标签:salary index name gender age 查询 job ES SpringBoot

springboot整个es有很多钟方法,比如TransportClient、RestClient、RestHighLevelClient、SpringData-Es、Elasticsearch-SQL等。

ElasticSearch 官方提供了 3 个 Client,具体如下:

  • org.elasticsearch.client.transport.TransportClient
  • org.elasticsearch.client.RestClient
  • org.elasticsearch.client.RestHighLevelClient

TransportClient 位于 Elasticsearch 包下,是 Elasticsearch 官方早期支持的 ElasticSearch Client,但是在 ElasticSearch 7.x 版本中已经标注为 Deprecated,并且将在 8.0 版本中移除,所以建议不使用 TransportClient 作为 ElasticSearch Client。
RestHighLevelClient 是 TransportClient 的直接替代者,也是 ElasticSearch 官方推荐和默认的 Client

准备数据

delete employees

PUT /employees/
{
  "mappings": {
    "properties": {
      "age": {
        "type": "integer"
      },
      "gender": {
        "type": "keyword"
      },
      "job": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 50
          }
        }
      },
      "name": {
        "type": "keyword"
      },
      "salary": {
        "type": "integer"
      }
    }
  }
}

PUT /employees/_bulk
{ "index" : {  "_id" : "1" } }
{ "name" : "Emma","age":32,"job":"Product Manager","gender":"female","salary":35000 }
{ "index" : {  "_id" : "2" } }
{ "name" : "Underwood","age":41,"job":"Dev Manager","gender":"male","salary": 50000}
{ "index" : {  "_id" : "3" } }
{ "name" : "Tran","age":25,"job":"Web Designer","gender":"male","salary":18000 }
{ "index" : {  "_id" : "4" } }
{ "name" : "Rivera","age":26,"job":"Web Designer","gender":"female","salary": 22000}
{ "index" : {  "_id" : "5" } }
{ "name" : "Rose","age":25,"job":"QA","gender":"female","salary":18000 }
{ "index" : {  "_id" : "6" } }
{ "name" : "Lucy","age":31,"job":"QA","gender":"female","salary": 25000}
{ "index" : {  "_id" : "7" } }
{ "name" : "Byrd","age":27,"job":"QA","gender":"male","salary":20000 }
{ "index" : {  "_id" : "8" } }
{ "name" : "Foster","age":27,"job":"Java Programmer","gender":"male","salary": 20000}
{ "index" : {  "_id" : "9" } }
{ "name" : "Gregory","age":32,"job":"Java Programmer","gender":"male","salary":22000 }
{ "index" : {  "_id" : "10" } }
{ "name" : "Bryant","age":20,"job":"Java Programmer","gender":"male","salary": 9000}
{ "index" : {  "_id" : "11" } }
{ "name" : "Jenny","age":36,"job":"Java Programmer","gender":"female","salary":38000 }
{ "index" : {  "_id" : "12" } }
{ "name" : "Mcdonald","age":31,"job":"Java Programmer","gender":"male","salary": 32000}
{ "index" : {  "_id" : "13" } }
{ "name" : "Jonthna","age":30,"job":"Java Programmer","gender":"female","salary":30000 }
{ "index" : {  "_id" : "14" } }
{ "name" : "Marshall","age":32,"job":"Javascript Programmer","gender":"male","salary": 25000}
{ "index" : {  "_id" : "15" } }
{ "name" : "King","age":33,"job":"Java Programmer","gender":"male","salary":28000 }
{ "index" : {  "_id" : "16" } }
{ "name" : "Mccarthy","age":21,"job":"Javascript Programmer","gender":"male","salary": 16000}
{ "index" : {  "_id" : "17" } }
{ "name" : "Goodwin","age":25,"job":"Javascript Programmer","gender":"male","salary": 16000}
{ "index" : {  "_id" : "18" } }
{ "name" : "Catherine","age":29,"job":"Javascript Programmer","gender":"female","salary": 20000}
{ "index" : {  "_id" : "19" } }
{ "name" : "Boone","age":30,"job":"DBA","gender":"male","salary": 30000}
{ "index" : {  "_id" : "20" } }
{ "name" : "Kathy","age":29,"job":"DBA","gender":"female","salary": 20000}

引入依赖

可以复制下边的依赖贴入POM文件,还可以在阿里云的脚手架上勾选,然后下载生成的工程

 <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.7.RELEASE</spring-boot.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-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>2.0.15</version>
        </dependency>

    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.7.RELEASE</version>
                <configuration>
                    <mainClass>com.tenic.springbootes.SpringbootEsApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

修改配置文件

# 应用名称
spring.application.name=springboot-es

elasticsearch.host=x.x.x.x
elasticsearch.port=9200
elasticsearch.username=
elasticsearch.password=

目录结构

image.png

创建配置类,配置ES相关信息,并创建RestHighLevelClient

@Configuration
public class ElasticsearchConfig {

    @Value("${elasticsearch.host}")
    private String host;

    @Value("${elasticsearch.port}")
    private int port;

    @Value("${elasticsearch.username}")
    private String userName;

    @Value("${elasticsearch.password}")
    private String password;

    @Bean(destroyMethod = "close")
    public RestHighLevelClient restClient() {
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY,
                new UsernamePasswordCredentials(userName, password));

        RestClientBuilder builder = RestClient.builder(new HttpHost(host, port))
                .setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));
        RestHighLevelClient client = new RestHighLevelClient(builder);
        return client;

    }
}

创建映射实体

@Data
public class Employees {

    private String name;

    private Integer age;

    private String gender;

    private String job;

    private Integer salary;
}

配置工具类

public interface Constant {
    String EMPLOYEES_INDEX = "employees";
}

创建测试类

@SpringBootTest
@RunWith(SpringRunner.class)
class SpringbootEsApplicationTests {
    @Test
    void contextLoads() {}
}

继承测试类,本地CRUD测试一下

public class SpringbootEsApplicationDemo1  extends SpringbootEsApplicationTests{

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    /**
     * 查询索引employees
     * @throws IOException
     */
    @Test
    public void test1() throws IOException {
        QueryBuilder queryBuilder = new MatchAllQueryBuilder();
        SearchResponse response = search(queryBuilder);
        printResponse(response);
    }

    /**
     * 插入文档
     * @throws IOException
     */
    @Test
    public void test2() throws IOException {
        Employees employees = new Employees("zhangsan",44,"male","CTO",3300);
        IndexRequest indexRequest = new IndexRequest(EMPLOYEES_INDEX);
        indexRequest.id("21").source(JSONObject.toJSONString(employees),XContentType.JSON);
        IndexResponse indexResponse = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        System.out.println("创建状态:"+indexResponse.status());
        System.out.println(indexResponse);
    }

    /**
     * 更新文档
     * @throws IOException
     */
    @Test
    public void test3() throws IOException {
        UpdateRequest updateRequest = new UpdateRequest(EMPLOYEES_INDEX,"21");
        Employees employee = new Employees();
        employee.setName("wangwu");
        updateRequest.doc(JSONObject.toJSONString(employee),XContentType.JSON);
        UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
        System.out.println("更新状态:"+update.status());
        System.out.println(update);
    }

    /**
     * 删除文档
     * @throws IOException
     */
    @Test
    public void test4() throws IOException {
        DeleteRequest deleteRequest = new DeleteRequest(EMPLOYEES_INDEX,"21");
        DeleteResponse deleteResponse = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
        System.out.println("删除状态:"+deleteResponse.status());
        System.out.println(deleteResponse);
    }

    /**
     * 高亮查询
     * @throws IOException
     */

    @Test
    public void test5() throws IOException {
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices(EMPLOYEES_INDEX);
        // term 查询
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        TermQueryBuilder query = new TermQueryBuilder("job","programmer");
        sourceBuilder.query(query);
        // 高亮查询
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        highlightBuilder.requireFieldMatch(false);
        highlightBuilder.field("*");
        sourceBuilder.highlighter(highlightBuilder);

        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println("查询状态:"+searchResponse.status());
        System.out.println("查询总条数:"+searchResponse.getHits().getTotalHits());
        printResponse(searchResponse);
    }

	/**
     * 查询索引
	 */
    private SearchResponse search(QueryBuilder query) throws IOException {
        SearchRequest searchSource = new SearchRequest();
        searchSource.indices(EMPLOYEES_INDEX);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(query);

        searchSource.source(sourceBuilder);
        SearchResponse response = restHighLevelClient.search(searchSource, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        System.out.println("查询状态:"+response.status());
        System.out.println("查询总条数:"+hits.getTotalHits());
        return response;
    }

    /**
     * 打印结果,并转换成实体对象
     */
    private void printResponse(SearchResponse response) {
        SearchHits hits = response.getHits();
        for (SearchHit hit : hits.getHits()) {
            Employees employees = JSONObject.parseObject(hit.getSourceAsString(), Employees.class);
            System.out.println(employees);
        }
    }
}

分页查询,search after,scroll api查询

public class SpringbootEsApplicationDemo2 extends SpringbootEsApplicationTests{

    @Autowired
    private RestHighLevelClient restHighLevelClient;


    /**
     * FROM/SIZE 分页查询,from:从指定行开始,size:需要查询页的条数
     * ES最大查询是10000条数据,所以要FROM+SIZE<=10000
     * @throws IOException
     */
    @Test
    public void test1() throws IOException {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        QueryBuilder queryBuilder = new MatchAllQueryBuilder();
        sourceBuilder.query(queryBuilder);
        sourceBuilder.from(2);
        sourceBuilder.size(5);

        processESCmd(sourceBuilder);
    }

    /**
     * search after 深度分页查询数据
     * @throws IOException
     */
    @Test
    public void test2() throws IOException {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        QueryBuilder queryBuilder = new MatchAllQueryBuilder();
        sourceBuilder.query(queryBuilder);
        sourceBuilder.size(19);
        sourceBuilder.sort("age", SortOrder.DESC);
        sourceBuilder.sort("_id",SortOrder.ASC);
        SearchResponse searchResponse = processESCmd(sourceBuilder);
        while(searchResponse.getHits().getHits().length>0) {
            SearchHit[] hits = searchResponse.getHits().getHits();
            SearchHit hit = hits[hits.length - 1];
            sourceBuilder.searchAfter(hit.getSortValues());
            searchResponse = processESCmd(sourceBuilder);
        }
    }

      /**
     * scroll api 查询
     * 基于快照查询,此时如果有新数据插入索引,该查询不会查到
     * 其中scrollRequest.scroll("1m");中设置的是scroll请求的上下文的存活时间
     * @throws IOException
     */
    @Test
    public void test3() throws IOException {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        QueryBuilder queryBuilder = new MatchAllQueryBuilder();
        sourceBuilder.query(queryBuilder);
        sourceBuilder.size(5);
        SearchRequest searchRequest = new SearchRequest(EMPLOYEES_INDEX);
        searchRequest.scroll("1m");
        searchRequest.source(sourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        while(search.getHits().getHits().length>0){
            for (SearchHit hit : search.getHits()) {
                System.out.println("ID:"+hit.getId()+"--"+ JSONObject.parseObject(hit.getSourceAsString(), Employees.class));
            }
            String scrollId = search.getScrollId();
            SearchScrollRequest scrollRequest = new SearchScrollRequest();
            scrollRequest.scrollId(scrollId);
            scrollRequest.scroll("1m");
            search = restHighLevelClient.scroll(scrollRequest,RequestOptions.DEFAULT);
        }

    }

    private SearchResponse processESCmd(SearchSourceBuilder sourceBuilder) throws IOException {
        SearchRequest searchRequest = new SearchRequest(EMPLOYEES_INDEX);
        searchRequest.source(sourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println("查询状态:"+search.status());
        System.out.println("查询条数:"+search.getHits().getHits().length);
        for (SearchHit hit : search.getHits()) {
            System.out.println("ID:"+hit.getId()+"--"+ JSONObject.parseObject(hit.getSourceAsString(), Employees.class));
        }
        return search;
    }
}

标签:salary,index,name,gender,age,查询,job,ES,SpringBoot
From: https://www.cnblogs.com/tenic/p/16795911.html

相关文章

  • ES大数据量的分页查询
    FROM/SIZE分页查询默认情况下,不加from,size的话,ES会返回前10条记录。加上from,size就会查询指定的条数。其中from代表起始行号,size代表查询行数。如果用JAVA等Client端传参......
  • ES的过滤查询
    ES的查询类型和特性查询(query):默认会计算每个返回文档的得分,然后根据得分排序过滤(filter):筛查出符合条件的文档,并且不计算得分,还可以缓存文档注意:filter过滤查询必须要......
  • Mysql单表访问方法,索引合并,多表连接原理,基于规则的优化,子查询优化
    参考书籍《mysql是怎样运行的》非常推荐这本书,通俗易懂,但是没有讲mysql主从等内容书中还讲解了本文没有提到的子查询优化内容,本文只总结了常见的子查询是如何优化的系......
  • ES聚合查询
    Elasticsearch的聚合查询分为四大类,分别是BucketAggregation、MetricAggregation、PipelineAggregation、MatrixAggregration。具体的四大类都是什么意思呢?都是怎么运......
  • ES中的DSL语句操作
    ES中的查询分为URISearch、RequestBodySearch。URISearch-在URL中使用查询参数。RequestBodySearch-使用JSON格式的入参作为查询条件。DSL语句就是基于Reques......
  • ES中的一些基本概念以及和关系数据库对比
    以下总结点为自己思路总结,有不正确地方,请斧正。ES中的基本概念一……索引索引:存放在ES中同一个类型文档的集合叫做ES中的索引,类似于关系数据库中的TableES中的基......
  • kubernetes学习笔记4-pod
    Pod资源定义​自主式pod资源,很少用到,手动创建的资源,用kubectldelete后不会自动创建,而使用pod控制器管理的才会按照用户期望的重新创建;​资源清单:一级字段(apiVersion|kind|m......
  • 绝杀processOn,这款UML画图神器,阿里字节都用疯了,你还不知道?
    大家好,我是陶朱公Boy,又和大家见面了。前言在文章开始前,想先问大家一个问题,大家平时在项目需求评审完后,是直接开始编码了呢?还是会先写详细设计文档,后再开始进行编码开发......
  • 实现查询连续3天登陆的用户
    sql写出连续三天都登录的用户1、创建表createtabletest_user_login_3days(user_idint,login_datestring); 2、数据准备insertintotest_user_login_3daysvalue......
  • Pytest进阶使用
    fixture特点:命令灵活:对于setup,teardown可以省略数据共享:在conftest.py配置里写方法可以实现数据共享,不需要import导入,可以跨文件共享scope的层次及神奇的yield组......