ElasticSearch集成SpringBoot与常见使用方法

时间:2020-06-07 18:01:27   收藏:0   阅读:42

一、导包

技术分享图片

二、核对导入的ES版本

我的springboot自动导入的是7.6.2的版本,但我搭建的ES是7.7.0,为了避免出异常,需修改导入版本与ES服务版本一致

技术分享图片

修改导入版本

  1. 查看springboot版本号使用的什么properties标签

    • 打开pom文件->按住ctrl点击artifactId

    技术分享图片

    • 在弹出的pom中按住Ctrl点击artifactId

      技术分享图片

    • 在弹出的pom中找到elasticsearch版本标签

      技术分享图片

    • 在项目的pom文件properties标签中添加需要导入的版本

      技术分享图片

    • 这时回到刚才第一张图,看es就会变成了指定的版本了

三、写配置类

我是用的是RestHighLevelClient ,通过官方文档得知,它需要返回一个RestHighLevelClient 对象,并且使用完后及时关闭客户端

技术分享图片

四、开始测试

索引操作

1.创建索引

注意:索引名字必须小写

返回值为:{"acknowledged":true,"fragment":false,"shardsAcknowledged":true}

这个返回值和elasticsearch-head创建索引返回的结果一样

技术分享图片

代码如下:

package com.rb.elasticsearch.elasticsearch;

import com.alibaba.fastjson.JSON;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;

@SpringBootTest
class ElasticsearchApplicationTests {
    @Autowired
    RestHighLevelClient restHighLevelClient;

    /**
     * 创建索引
     * @throws IOException
     */
    @Test
    void createIndex() throws IOException {
        CreateIndexRequest request = new CreateIndexRequest("java_index");
        CreateIndexResponse createIndexResponse =restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
        System.out.println(JSON.toJSONString(createIndexResponse));//返回值
    }

}

2.查看索引是否存在

    /**
     * 判断索引是否存在
     * @throws IOException
     */
    @Test
    void checkIndex() throws IOException {
        GetIndexRequest getIndexRequest=new GetIndexRequest("java_index");
        boolean exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
        System.out.println(exists);//返回值true:存在 false:不存在
    }

3.删除索引

acknowledged=true表示删除成功

    /**
     * 判断索引是否存在
     * @throws IOException
     */
    @Test
    void delIndex() throws IOException {
        DeleteIndexRequest deleteIndexRequest=new DeleteIndexRequest("java_index");
        AcknowledgedResponse delete = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
        System.out.println(JSON.toJSONString(delete));//返回值{"acknowledged":true,"fragment":false}
    }

文档操作

官方举例是手拼json串,但工作中很少这么用,大多数都是一个model,然后转成json串,所以先创建一个model

package com.rb.elasticsearch.model;

import lombok.Data;

@Data
public class Users {
    String name;
    String remark;
    int age;
}

1.添加文档

2.查看文档是否存在

    /**
     * 查看文档是否存在
     * @throws IOException
     */
    @Test
    void checkDocIsExist() throws IOException {
        if(checkIndexIsExist()){
            GetRequest getRequest=new GetRequest(Es.INDEX_NAME,"1");
            boolean exists = restHighLevelClient.exists(getRequest, RequestOptions.DEFAULT);
            System.out.println(exists);//true 存在 false 不存在
        }else{
            System.out.println("索引不存在");
        }
    }

3.修改文档

注意:我的users对象中age是int,默认值是0,如果执行下面批量修改的时候,age不修改的话会默认是0,这样会将相关索引中age字段值全部修改为0,可以使用Integer

 /**
     * 单一修改数据
     * @throws IOException
     */
    @Test
    void updateDoc() throws IOException {
        if(checkIndexIsExist()){
            UpdateRequest updateRequest=new UpdateRequest(Es.INDEX_NAME,"1");
            Users users=new Users();
            users.setAge(99);//只修改年龄,其他不动
            updateRequest.doc(JSON.toJSONString(users),XContentType.JSON);
            restHighLevelClient.update(updateRequest,RequestOptions.DEFAULT);
        }
    }

4.删除文档

    /**
     * 删除文档
     * @throws IOException
     */
    @Test
    void delDoc() throws IOException {
        if(checkIndexIsExist()){//只有索引已经创建的时候才可以继续
            DeleteRequest deleteRequest=new DeleteRequest("java_index","1");
            DeleteResponse delete = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
            System.out.println(delete);
        }
    }
/**
     * 批量删除
     * @throws IOException
     */
    @Test
    void buleDelDoc() throws IOException {
        if(checkIndexIsExist()){
            BulkRequest bulkRequest=new BulkRequest();
            for (int i = 0; i <5 ; i++) {
                int id =i+1;
                DeleteRequest deleteRequest=new DeleteRequest(Es.INDEX_NAME);
                deleteRequest.id(String.valueOf(id));
                bulkRequest.add(deleteRequest);
            }
            restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);
        }
    }

五.文档常用查询

单一字段查询

根据id精准查询

 /**
     * 根据id查询
     * @throws IOException
     */
    @Test
    void termSelectById() throws IOException {
        if(checkIndexIsExist()){
            GetRequest getRequest1 = new GetRequest(Es.INDEX_NAME, "1");
            //也可使用下面的方式
            //GetRequest getRequest=new GetRequest(Es.INDEX_NAME);
            //getRequest.id("1");
            GetResponse documentFields = restHighLevelClient.get(getRequest1, RequestOptions.DEFAULT);
            System.out.println(JSON.toJSONString(documentFields));
        }
    }

根据某字段精准查询

(select * from users where age=1)

  /**
       * 根据某字段精准查询
       * @throws IOException
       */
      @Test
      void termSelectByField() throws IOException {
          if(checkIndexIsExist()){
              SearchRequest searchRequest=new SearchRequest(Es.INDEX_NAME);
              SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
              searchSourceBuilder.query(QueryBuilders.termQuery("age",1));
              searchRequest.source(searchSourceBuilder);
              SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
              System.out.println(JSON.toJSONString(search));
          }
      }

根据某字段模糊查询

(select * from users where remark like ‘%0%‘)

/**
     * 根据某个字段模糊查询
     * @throws IOException
     */
    @Test
    void matchSelectByField() throws IOException {
        if(checkIndexIsExist()){
            SearchRequest searchRequest=new SearchRequest(Es.INDEX_NAME);
            SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
            searchSourceBuilder.query(QueryBuilders.matchQuery("remark","0"));
            searchRequest.source(searchSourceBuilder);
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            System.out.println(JSON.toJSONString(search.getHits().getHits()));
        }
    }

多条件查询

多条件And查询

(select * from users where name like ‘%因为是match,会被分词%‘ and age=0)

    /**
     * 多条件查询
     * @throws IOException
     */
    @Test
    void multipleFieldSelectByMust() throws IOException {
        if(checkIndexIsExist()){
            SearchRequest searchRequest = new SearchRequest(Es.INDEX_NAME);//定义请求
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//构建查询条件器
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();//选择返回值(满足查询条件的返回true,不满足是false)
            boolQueryBuilder.must(QueryBuilders.matchQuery("name","李0的名字叫李0"));//查询条件一
            boolQueryBuilder.must(QueryBuilders.termQuery("age","0"));//查询条件二
            System.out.println(boolQueryBuilder.must());//输出构建好的查询条件一、二
            searchSourceBuilder.query(boolQueryBuilder);//将条件完善的对象放入
            searchRequest.source(searchSourceBuilder);//向查询请求中放入查询条件
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);//执行查询
            System.out.println(JSON.toJSONString(search.getHits().getHits()));//查看结果
        }
    }

这一步我认为有点绕,java代码逻辑和上一篇说的命令先后逻辑是一样的,我的研究方式为逆推法(自己这么起的名字)

GET users/_doc/_search //后的_search就是 SearchRequest 定义请求
{
  "query":{//searchSourceBuilder.query(boolQueryBuilder);//将条件完善的对象放入
    "bool":{//BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();//选择返回值(满足查询条件的返回true,不满足是false)
      "must":[//boolQueryBuilder.must()
        {
          "term"://QueryBuilders.termQuery("age","0");每调用一次就多一个查询条件
          {
            "name":"张三的名字叫张三"
          }
        } , 
         {
          "match"://QueryBuilders.matchQuery("name","李0的名字叫李0")
          {
            "age":"15"
          }
        }
      ]
    }
  }
}

多条件OR查询

(select * from users where remark like ‘%1%‘ or age=0) 注:%1%里的1使用了match,会被分词

/**
     * 多条件查询OR
     * @throws IOException
     */
    @Test
    void multipleFieldSelectByShould() throws IOException {
        if(checkIndexIsExist()){
            SearchRequest searchRequest = new SearchRequest(Es.INDEX_NAME);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            boolQueryBuilder.should(QueryBuilders.matchQuery("remark","1"));
            boolQueryBuilder.should(QueryBuilders.termQuery("age","0"));
            searchSourceBuilder.query(boolQueryBuilder);
            searchRequest.source(searchSourceBuilder);
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            System.out.println(JSON.toJSONString(search.getHits().getHits()));
        }
    }

多条件!=查询

(select * from users where age !=0 and age !=1)

/**
     * 多条件查询!=
     * @throws IOException
     */
    @Test
    void multipleFieldSelectByMustNot() throws IOException {
        if(checkIndexIsExist()){
            SearchRequest searchRequest = new SearchRequest(Es.INDEX_NAME);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            boolQueryBuilder.mustNot(QueryBuilders.termQuery("age","1"));//QueryBuilders里面的查询方式可以随意换
            boolQueryBuilder.mustNot(QueryBuilders.termQuery("age","0"));//QueryBuilders里面的查询方式可以随意换
            searchSourceBuilder.query(boolQueryBuilder);
            searchRequest.source(searchSourceBuilder);
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            System.out.println(JSON.toJSONString(search.getHits().getHits()));
        }
    }

范围查询

(select * from users where age >=0 and age <=2)

gt 大于
gte 大于等于
lt 小于
lte 小于等于!

 /**
     * 根据字段范围查询
     * @throws IOException
     */
    @Test
    void multipleFieldSelectByRange() throws IOException {
        if(checkIndexIsExist()){
            SearchRequest searchRequest = new SearchRequest(Es.INDEX_NAME);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            //再此处还可以加上面的各种查询条件↓↓↓
            //再此处还可以加上面的各种查询条件↑↑↑
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("age").gte(0));
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("age").lte(2));
            searchSourceBuilder.query(boolQueryBuilder);
            searchRequest.source(searchSourceBuilder);
            restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            System.out.println(JSON.toJSONString(search.getHits().getHits()));
        }
    }

自定义字段返回

    /**
     * 显示指定字段
     * @throws IOException
     */
    @Test
    void returnField() throws IOException {
        if(checkIndexIsExist()){
            SearchRequest searchRequest = new SearchRequest(Es.INDEX_NAME);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            String[] includeFields = new String[] {"name", "age"};//要显示的哪些字段
            String[] excludeFields = new String[] {""};//要排除的哪些字段
            searchSourceBuilder.fetchSource(includeFields,excludeFields);
            searchRequest.source(searchSourceBuilder);
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            System.out.println(JSON.toJSONString(search.getHits().getHits()));
        }
    }

排序

select * from users where remark like ‘%的备注%‘ and remark like ‘%3%‘ order by _score desc , age desc

查询包含“的备注”、“3”的记录(传入参数会被分词),并且按照匹配度_score这个字段排序,数值越大的匹配度越高,然后按照年龄age降序排序

/**
     * 排序
     * @throws IOException
     */
    @Test
    void sort() throws IOException {
        if(checkIndexIsExist()){
            SearchRequest searchRequest = new SearchRequest(Es.INDEX_NAME);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            searchSourceBuilder.query(QueryBuilders.matchQuery("remark","的备注 3"));
            searchSourceBuilder.sort("_score",SortOrder.DESC);
            searchSourceBuilder.sort("age",SortOrder.DESC);
            searchRequest.source(searchSourceBuilder);
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            System.out.println(JSON.toJSONString(search));
        }
    }

高亮查询

public String test() throws IOException {
        SearchRequest searchRequest=new SearchRequest(Es.INDEX_NAME);
        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
        //构建查询条件start
        searchSourceBuilder.query(QueryBuilders.matchQuery("name","名 叫"));//模糊搜索
        //searchSourceBuilder.query(QueryBuilders.termQuery("name.keyword","李0的名字叫李0"));//精准搜索
        //构建查询条件end
        //高亮start
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name");
        //highlightBuilder.field("name.keyword");//与上方设置的name保持一致
        highlightBuilder.preTags("<mytag style=‘color:red‘>");//自定义标签&样式
        highlightBuilder.postTags("</mytag>");//自定义标签&样式
        searchSourceBuilder.highlighter(highlightBuilder);
        //高亮end
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        List<Map<String, Object>> list=new ArrayList();
        //高亮条件封装start
        for (SearchHit hit : search.getHits().getHits()) {
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField remark = highlightFields.get("name");
           // HighlightField remark = highlightFields.get("name.keyword");//与上方设置的name保持一致
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            if(remark!=null){
                Text[] fragments = remark.fragments();
                String desc="";
                for (Text fragment : fragments) {
                    desc+=fragment;
                }
                //sourceAsMap.put("name.keyword",desc);
                sourceAsMap.put("name",desc);
                list.add(sourceAsMap);
            }
        }
        //高亮条件封装end
        return JSON.toJSONString(search);
    }

结果如下:

技术分享图片

获得指定索引下满足条件的总记录数据

    /**
     * 查询指定索引中总共有多少条数据
     * @throws IOException
     */
    @Test
    void getTotalCount() throws IOException {
        CountRequest countRequest = new CountRequest(Es.INDEX_NAME);
        //可以自定义设置上面的一些查询条件start
        //可以自定义设置上面的一些查询条件end
        CountResponse count = restHighLevelClient.count(countRequest, RequestOptions.DEFAULT);
        System.out.println(JSON.toJSONString(count));
    }

分页查询

from:从第几条数据开始(>关系,非>=)
size:查询几条数据

/**
     * 分页查询
     * @throws IOException
     */
    @Test
    void pageSelect() throws IOException {
        if(checkIndexIsExist()){
            SearchRequest searchRequest=new SearchRequest(Es.INDEX_NAME);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            //设置搜索条件
            searchSourceBuilder.query(QueryBuilders.matchQuery("remark","的备注"));
            searchSourceBuilder.from(2);//从索引第几个开始查找,索引从0 开始
            searchSourceBuilder.size(2);//显示from至from+size的数据
            //例如:查询id1~2的数据,from=0 ,size=2
            //     查询id3-4的数据,from=2,  size=2
            searchRequest.source(searchSourceBuilder);
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            System.out.println(JSON.toJSONString(search.getHits().getHits()));
        }
    }

六、集成好的项目

https://files-cdn.cnblogs.com/files/rb2010/elasticsearch.zip

原文:https://www.cnblogs.com/rb2010/p/13061353.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!