springboot整合ES

  • 添加文档,有三种方式

    POST请求	http://localhost:9200/books/_doc		#使用系统生成id
    POST请求	http://localhost:9200/books/_create/1	#使用指定id
    POST请求	http://localhost:9200/books/_doc/1		#使用指定id,不存在创建,存在更新(版本递增)
    
    文档通过请求参数传递,数据格式json
    {
        "name":"springboot",
        "type":"springboot",
        "description":"springboot"
    }  
    
  • 查询文档

    GET请求	http://localhost:9200/books/_doc/1		 #查询单个文档 		
    GET请求	http://localhost:9200/books/_search		 #查询全部文档
    
  • 条件查询

    GET请求	http://localhost:9200/books/_search?q=name:springboot	# q=查询属性名:查询属性值
    
  • 删除文档

    DELETE请求	http://localhost:9200/books/_doc/1
    
  • 修改文档(全量更新)

    PUT请求	http://localhost:9200/books/_doc/1
    
    文档通过请求参数传递,数据格式json
    {
        "name":"springboot",
        "type":"springboot",
        "description":"springboot"
    }
    
  • 修改文档(部分更新)

    POST请求	http://localhost:9200/books/_update/1
    
    文档通过请求参数传递,数据格式json
    {			
        "doc":{						#部分更新并不是对原始文档进行更新,而是对原始文档对象中的doc属性中的指定属性更新
            "name":"springboot"		#仅更新提供的属性值,未提供的属性值不参与更新操作
        }
    }
    

在Springboot整合ES提供了启动依赖jar。 该jar包封了一个类: RestHighLevelClient
该类可以对象ES中各个接口进行相应的操作。

1. 新建项目

创建springboot工程并导入相关的依赖 2.3.12.RELEASE。最新版spring boot2.7.5中RestHighLevelClient已过时

在这里插入图片描述
ElasticsearchRestTemplate 操作形式是ES早期的操作方式,使用的客户端被称为Low Level Client,这种客户端操作方式性能方面略显不足,于是ES开发了全新的客户端操作方式,称为High Level Client。高级别客户端与ES版本同步更新,但是springboot最初整合ES的时候使用的是低级别客户端,所以企业开发需要更换成高级别的客户端模式。

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>

spring-boot整合elasticsearch的jar里面封装的也有RestHighLevelClient

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

2. 创建配置类

创建一个配置类,返回 RestHighLevelClient

package com.aaa.config;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;

/**
 * @author shang tf
 * @createTime 2022/11/10 18:33
 * @since 1.0.0
 */
public class ESConfig {
    //springboot连接ES提供的一个客户端类。RestHighLevelClient
    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestHighLevelClient client=new RestHighLevelClient(
                RestClient.builder(new HttpHost("127.0.0.1",9200,"http"))
        );
        return client;
    }
}

RestHighLevelClient的常见API

@Autowired
private RestHighLevelClient client;
操作名称相关API
创建ES的索引client.indices().create(…)
判断索引是否存在client.indices().exists(…)
删除索引client.indices().delete(…)
    //创建ES的索引
    @Test
    void createIndex() throws Exception{
        //创建CreateIndexRequest请求类---对应索引的创建需要的参数 都封装到该类中
        CreateIndexRequest indexRequest=new CreateIndexRequest("qy156");
        //关于对索引操作的功能都IndiceClient类中
        CreateIndexResponse indexResponse = client.indices().create(indexRequest, RequestOptions.DEFAULT);

        System.out.println("是否创建索引成功:"+indexResponse.isAcknowledged());
    }

    //判断索引是否存在.
    @Test
    public void isExist() throws IOException {
        GetIndexRequest getIndexRequest=new GetIndexRequest("qy156");
        boolean exists = client.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
        System.out.println("索引是否存在:"+exists);
    }

    //删除索引:
    @Test
    public void delete() throws IOException{
        DeleteIndexRequest deleteIndexRequest=new DeleteIndexRequest("qy158");
        AcknowledgedResponse delete = client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);

        System.out.println("是否删除成功:"+delete.isAcknowledged());
    }

使用IK分词器创建索引:

@Test
void testCreateIndexByIK() throws IOException {
    CreateIndexRequest request = new CreateIndexRequest("books");
    String json = "{\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" +
            "            \"type\":{\n" +
            "                \"type\":\"keyword\"\n" +
            "            },\n" +
            "            \"description\":{\n" +
            "                \"type\":\"text\",\n" +
            "                \"analyzer\":\"ik_max_word\",\n" +
            "                \"copy_to\":\"all\"\n" +
            "            },\n" +
            "            \"all\":{\n" +
            "                \"type\":\"text\",\n" +
            "                \"analyzer\":\"ik_max_word\"\n" +
            "            }\n" +
            "        }\n" +
            "    }\n" +
            "}";
    //设置请求中的参数
    request.source(json, XContentType.JSON);
    client.indices().create(request, RequestOptions.DEFAULT);
}

source方法是传递请求体,之前在命令行中添加的请求体,可以在source中传递
在这里插入图片描述

操作文档:

操作名称相关API
往索引中添加文档client.index(…)
根据id查询文档内容client.get(…)
根据id删除文档client.delete(…)
修改文档client.update(…)
    //往索引中添加文档
    @Test
    public void insertDoc() throws IOException {

        IndexRequest indexRequest=new IndexRequest("qy156");
        //指定文档的id值
        indexRequest.id("1");
        //指定文档的内容
        Student student=new Student("李四","郑州","男",18);
        indexRequest.source(JSON.toJSONString(student), XContentType.JSON);

        IndexResponse index = client.index(indexRequest, RequestOptions.DEFAULT);

        System.out.println("结果:"+index.getResult());
    }

    //根据id查询文档内容
    @Test
    public void findByid() throws IOException {
        GetRequest getRequest=new GetRequest("qy156");
        getRequest.id("1");
        GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
        //getSourceAsMap:拿到的结果封装为Map
        Map<String, Object> sourceAsMap = getResponse.getSourceAsMap();
        System.out.println(sourceAsMap.get("name")+"===="+sourceAsMap.get("sex"));

        //getSourceAsString:拿到的结果为一个字符串
        String sourceAsString = getResponse.getSourceAsString();
        System.out.println(sourceAsString);
    }

    //根据id删除文档
    @Test
    public void deleteByid() throws  IOException{
        DeleteRequest deleteRequest=new DeleteRequest("qy156");
        deleteRequest.id("1");
        DeleteResponse delete = client.delete(deleteRequest, RequestOptions.DEFAULT);
        System.out.println(delete.getResult());
    }

    //修改文档
    @Test
    public void update() throws  IOException{
        UpdateRequest updateRequest=new UpdateRequest("qy156","1");
        Student student=new Student();
        student.setName("张学友");
        updateRequest.doc(JSON.toJSONString(student),XContentType.JSON);

        UpdateResponse update = client.update(updateRequest, RequestOptions.DEFAULT);
        System.out.println(update.getResult());
    }

	//批量添加
    @Test
    public void testBulkDoc() throws Exception{
        BulkRequest bulkRequest=new BulkRequest("qy150-index");
        List<User> list=new ArrayList<>();
        list.add(new User("古天乐","北京",35));
        list.add(new User("张家辉","郑州",22));
        list.add(new User("刘嘉玲","苏州",32));
        list.add(new User("刘青云","香港",26));
        list.add(new User("姜皓文","商丘",18));
        list.add(new User("闫克起","河南",16));

        for (User user:list){
              IndexRequest indexRequest=new IndexRequest();
              indexRequest.source(JSON.toJSONString(user),XContentType.JSON);
              bulkRequest.add(indexRequest);
        }

        BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);

        System.out.println(bulkResponse.hasFailures());
    }

es的搜索功能

	//搜索查询
    @Test
    public void testSearchDoc() throws Exception {
        SearchRequest searchRequest=new SearchRequest("qy150-index");

        //构建一个条件类对象
        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();

        //查询参数
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "刘");
        searchSourceBuilder.query(matchQueryBuilder);

        //构建分页
        searchSourceBuilder.from(0);
        searchSourceBuilder.size(8);

        //构建高亮
        HighlightBuilder highlightBuilder=new HighlightBuilder();
        highlightBuilder.field("name");
        highlightBuilder.preTags("<font color='red'>");
        highlightBuilder.postTags("</font>");
        searchSourceBuilder.highlighter(highlightBuilder);

        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        SearchHits hits = searchResponse.getHits();

        System.out.println("总条数:"+hits.getTotalHits().value);

        System.out.println("====================获取当前页的记录===========================");
        SearchHit[] hits1 = hits.getHits();
//        for (SearchHit hit:hits1){
//            System.out.println(hit.getSourceAsMap());
//        }
        System.out.println("===================高亮字段==============================");
        for (SearchHit hit:hits1){
            System.out.println(hit.getHighlightFields().get("name").getFragments()[0]);
        }

    }

eg:

package com.aaa.service;

import com.aaa.config.entity.Product;
import com.aaa.config.entity.Result;
import com.aaa.utils.ParseJdHtml;
import com.alibaba.fastjson.JSON;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
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.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author shang tf
 * @createTime 2022/11/11 17:35
 * @since 1.0.0
 */
@Service
public class JdService {
    @Autowired
    private RestHighLevelClient client;

    public Result search(String keyword) throws Exception {
        SearchRequest searchRequest = new SearchRequest("jd");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("pname", keyword);
        sourceBuilder.query(queryBuilder);

        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("pname");
        highlightBuilder.preTags("<font color='red'>");
        highlightBuilder.postTags("</font>");
        sourceBuilder.highlighter(highlightBuilder);

        searchRequest.source(sourceBuilder);

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        List<Map<String, Object>> list = new ArrayList<>();
        for (SearchHit hit : hits) {
            Map<String, Object> map = hit.getSourceAsMap();
            String pname = hit.getHighlightFields().get("pname").getFragments()[0].toString();
            map.put("pname",pname);
            list.add(map);
        }
        return new Result(200, "查询成功", list);
    }

    public Result insert(String keyword) throws Exception {
        List<Product> products = ParseJdHtml.parseJd(keyword);
        BulkRequest bulkRequest = new BulkRequest("jd");

        for (Product product : products) {
            bulkRequest.add(new IndexRequest().source(JSON.toJSONString(product), XContentType.JSON));
        }
        BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);
        if (!bulk.hasFailures()) {
            return new Result(200, "查询成功", null);
        }
        return new Result(500, "查询失败", null);
    }
}

小知识:

  • alt+insert
    SpringBoot测试类中SetUp Method 和 TearDown Method 方法
    执行测试之前执行(SetUp Method),
    执行测试之后执行(TearDown Method)
    在这里插入图片描述在这里插入图片描述
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐