springBoot 整合elasticsearch7.6

springBoot 整合elasticsearch7.6

  • 1.elasticsearch5.5与elasticsearch7.6的区别
  • 2.创建一个springBoot项目
  • 3.配置RestHighLevelClient
  • 3.elasticsearch7.6增删查改

公司的项目里用到了一个叫elasticsearch5.5的框架,我不知道是啥,很多原理还不懂,于是自己从零搭建 与springBoot 整合。我只稍微写了一点点简单的查询,具体的请参考官网,附上链接

RestHighLevelClient官方文档: https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-create-index.html.

spring-data-elasticsearch官方文档: http://jvm123.com/doc/es/index.html#elasticsearch.clients.rest.

1.elasticsearch5.5与elasticsearch7.6的区别

1). elasticsearch5.5 index支持多种type,elasticsearch7.6 索引将去除type 没有类型的概念了。
官网原文如下:springBoot 整合elasticsearch7.6_第1张图片
在编辑器中创建索引时候也可以看到已被弃用的方法,如图,我们点进去看
在这里插入图片描述
可以看到有个@Deprecated,这个注解的含义是 这个方法或类不再建议使用。在新版本中有其他方法或类可以代替这个使用,以后的版本也不会再更新这个方法或类。注释上写的也是差不多这个意思。
springBoot 整合elasticsearch7.6_第2张图片

2).在Elasticsearch Java客户端也有区别。在 Elasticsearch 7.6 中不建议使用TransportClient,并且在8.0中会完全删除TransportClient。因此,官方更建议我们用Java High Level REST Client ,而在低版本中则使用Java Low Level REST Client。

2.创建一个springBoot项目

springBoot 整合elasticsearch7.6_第3张图片
springBoot 整合elasticsearch7.6_第4张图片

springBoot 整合elasticsearch7.6_第5张图片
添加jar包

    
        cn.hutool
        hutool-all
        5.3.2
    


    
    
        org.elasticsearch.client
        elasticsearch-rest-high-level-client
        7.6.2
    


    
    
        org.springframework.data
        spring-data-elasticsearch
        4.0.1.RELEASE
    

springBoot 整合elasticsearch7.6_第6张图片

3.配置RestHighLevelClient

我们使用RestHighLevelClient 来操作elasticsearch

package org.java.demo.config;

import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.RestClients;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;

public class RestClientConfig extends AbstractElasticsearchConfiguration {

    @Override
    @Bean
    public RestHighLevelClient elasticsearchClient() {

        final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                .connectedTo("localhost:9200")
                .build();

        return RestClients.create(clientConfiguration).rest();
    }
}

创建索引对象

package org.java.demo;

import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;

import java.io.Serializable;


@Document(indexName = "javashop")
public class GoodsIndex implements Serializable {


    @Id
    private Integer goodsId;



    @Field(analyzer = "ik_max_word")
    private String goodsName;

    /**
     * 农贸市场ID
     * */
    private String connet;

    public GoodsIndex() {

    }
    public String getConnet() {
        return connet;
    }

    public void setConnet(String connet) {
        this.connet = connet;
    }
    public Integer getGoodsId() {
        return goodsId;
    }

    public void setGoodsId(Integer goodsId) {
        this.goodsId = goodsId;
    }

    public String getGoodsName() {
        return goodsName;
    }

    public void setGoodsName(String goodsName) {
        this.goodsName = goodsName;
    }

    @Override
    public String toString() {
        return "GoodsIndex{" +
                "goodsId=" + goodsId +
                ", goodsName='" + goodsName + '\'' +
                ", connet='" + connet + '\'' +
                '}';
    }
}

springBoot 整合elasticsearch7.6_第7张图片

3.elasticsearch7.6增删查改

这里着重讲一下查询,termQuery与matchQuery的区别
TermQueryBuilder:
词条查询是ElasticSearch的一个简单查询。它仅匹配在给定字段中含有该词条的文档,而且是确切的、未经分析的词条。term查询会查找我们设定的准确值。term查询本身很简单,它接受一个字段名和我们希望查找的值。

TermsQueryBuilder:
词条查询(Term Query)允许匹配单个未经分析的词条,多词条查询(Terms Query)可以用来匹配多个这样的词条。只要指定字段包含任一我们给定的词条,就可以查询到该文档。

package org.java.demo;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.json.JSONObject;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;


import cn.hutool.core.collection.CollUtil;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.client.indices.*;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;



@RestController
@RequestMapping("/elasticsearch")
public class HelloController {

    @Autowired
    RestHighLevelClient highLevelClient;

    private  ElasticsearchOperations elasticsearchOperations;


    public HelloController(ElasticsearchOperations elasticsearchOperations) {
        this.elasticsearchOperations = elasticsearchOperations;
    }


    @GetMapping("/template")
    public void putTemplate()throws IOException{
        PutIndexTemplateRequest request = new PutIndexTemplateRequest("goods_template");
        //别名,所有根据该模版创建的index 都会添加这个别名。查询时可查询别名,就可以同时查询多个名称不同的index,根据此方法可实现index每天或每月生成等逻辑。
        request.alias(new Alias("goods_index"));
        request.order(10);
        //匹配哪些index。在创建index时会生效。
        request.patterns(CollUtil.newArrayList("goods_index*"));
        request.settings(Settings.builder()
                //数据插入后多久能查到,实时性要求高可以调低
                .put("index.refresh_interval", "1s")
                //传输日志,对数据安全性要求高的 设置 request,默认值:request
                .put("index.translog.durability", "async")
                .put("index.translog.sync_interval", "120s")
                //分片数量
                .put("index.number_of_shards", "5")
                //副本数量
                .put("index.number_of_replicas", "0")
                //单次最大查询数据的数量。默认10000。不要设置太高,如果有导出需求可以根据查询条件分批次查询。
                .put("index.max_result_window", "100000"));
        //使用官方提供的工具构建json。可以直接拼接一个json字符串,也可以使用map嵌套。
        XContentBuilder jsonMapping = XContentFactory.jsonBuilder();
        //所有数据类型 看官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/7.4/mapping-types.html#_core_datatypes
        jsonMapping.startObject().startObject("properties")
                .startObject("goodsName").field("type", "text").field("analyzer", "ik_max_word").endObject()
                .startObject("goodsId").field("type", "integer").endObject()
                //keyword类型不会分词存储
                .startObject("connet").field("type", "text").endObject()
                //指定分词器
                .endObject().endObject();
        request.mapping(jsonMapping);
        //设置为true只强制创建,而不是更新索引模板。如果它已经存在,它将失败
        request.create(false);
        AcknowledgedResponse response = highLevelClient.indices().putTemplate(request, RequestOptions.DEFAULT);
        if (response.isAcknowledged()) {
            Console.log("创建模版成功!");
        } else {
            Console.log("创建模版失败!");
        }
    }


    @DeleteMapping("")
    public void deleteIndex(Integer id) throws IOException {
//        DeleteIndexRequest request = new DeleteIndexRequest("goods_index*");
          DeleteRequest  request = new DeleteRequest("goods_index",id.toString());
         DeleteResponse delete = highLevelClient.delete(request,RequestOptions.DEFAULT);
//        AcknowledgedResponse response = highLevelClient.indices().delete(request, RequestOptions.DEFAULT);
    }



    @PostMapping("/create")
    public void createIndex() throws IOException {
        CreateIndexRequest request = new CreateIndexRequest("goods_index_tmp");
        CreateIndexResponse createIndexResponse = highLevelClient.indices().create(request, RequestOptions.DEFAULT);
        if (createIndexResponse.isAcknowledged()) {
            Console.log("创建index成功!");
        } else {
            Console.log("创建index失败!");
        }
    }

    @PostMapping("")
    public void insertIndex() throws IOException {
        BulkRequest request = new BulkRequest("goods_index_" + DateUtil.format(new Date(), "yyyyMM"));
        for (int i = 0; i < 5; i++) {
            GoodsIndex testData = new GoodsIndex();
            testData.setGoodsId(i);
            testData.setConnet(i+"号商品简介----------------");
            testData.setGoodsName("商品---------------"+i);
            IndexRequest indexRequest = new IndexRequest("goods_index_" + DateUtil.format(new Date(), "yyyyMM"));
            indexRequest.id(testData.getGoodsId().toString());
            indexRequest.source(new JSONObject(testData).toString()
                    , XContentType.JSON);
            request.add(indexRequest);
        }
        BulkResponse response = highLevelClient.bulk(request, RequestOptions.DEFAULT);
        Console.log("插入状态:{} 数量:{} ",response.status(),response.getItems().length);
    }

    @PutMapping("")
    public void update(Integer id) throws IOException {
        UpdateRequest updateRequest = new UpdateRequest("goods_index", id.toString());
        GoodsIndex goodsIndex=new GoodsIndex();
        goodsIndex.setGoodsId(id);
        goodsIndex.setGoodsName("未知商品");
        goodsIndex.setConnet("未知内容");
        updateRequest.doc(new JSONObject(goodsIndex).toString()
                , XContentType.JSON);
        highLevelClient.update(updateRequest, RequestOptions.DEFAULT);
    }

    @GetMapping("")
    public void query(String keyword,Integer id) throws IOException {
        SearchRequest searchRequest = new SearchRequest("goods_index");
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("goodsName", keyword)
                .fuzziness(Fuzziness.AUTO)
                .analyzer("ik_max_word")
                .operator(Operator.AND)
                .prefixLength(3)
                .maxExpansions(10);

        boolQueryBuilder.must(QueryBuilders.termQuery("goodsId", id));
        boolQueryBuilder.must(matchQueryBuilder);

        searchSourceBuilder.query(boolQueryBuilder);
        searchSourceBuilder.from(0);
        searchSourceBuilder.size(5);
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        searchSourceBuilder.sort(new FieldSortBuilder("goodsId").order(SortOrder.ASC));

        searchRequest.source(searchSourceBuilder);

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

        SearchHits hits = searchResponse.getHits();
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            Map map = hit.getSourceAsMap();
            System.out.println(hit);
            
        }
    }
}

你可能感兴趣的:(springboot,elasticsearch,RestHighLevel)