Elasticsearch整合SpringBoot案例

Posted 阿波罗的手

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Elasticsearch整合SpringBoot案例相关的知识,希望对你有一定的参考价值。

 1、elasticsearch官方文档的使用与介绍

1.1、Rest客户端初始化官方文档链接:

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-getting-started-initialization.html#java-rest-high-getting-started-initialization

RestHighLevelClient client = new RestHighLevelClient(
        RestClient.builder(
                new HttpHost("localhost", 9200, "http"),
                new HttpHost("localhost", 9201, "http")));

1.2、RequestOptions官方文档链接

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-low-usage-requests.html#java-rest-low-usage-request-options

RequestOptions类包含应共享的部分请求在同一应用程序中的多个请求之间。通过RequestOptions对请求进行统一设置

private static final RequestOptions COMMON_OPTIONS;
static {
    RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
    builder.addHeader("Authorization", "Bearer " + TOKEN); 
    builder.setHttpAsyncResponseConsumerFactory(           
        new HttpAsyncResponseConsumerFactory
            .HeapBufferedResponseConsumerFactory(30 * 1024 * 1024 * 1024));
    COMMON_OPTIONS = builder.build();
}

1.3、对数据进行保存,创建Index索引官方文档

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-document-index.html#java-rest-high-document-index

选择在哪个索引中存储数据,并且设置“键”-“存储的值”:

IndexRequest indexRequest = new IndexRequest("posts").id("1").source(要存储的JSON数据)

 执行存储:

IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);

 1.4、对数据进行查询官方文档

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-search.html

所有的根操作都可以根据SearchSourceBuilder进行实现:

SearchRequest searchRequest = new SearchRequest(); 
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); 
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
searchSourceBuilder.size();
searchSourceBuilder.from(); searchRequest.source(searchSourceBuilder);

使用同步方式进行查询执行

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

要获取筛选后的数据,我们首先需要获取响应中包含的 SearchHits:

SearchHits hits = searchResponse.getHits();

SearchHits 提供有关所有命中的全局信息,例如命中总数或最高分数:

TotalHits totalHits = hits.getTotalHits();
//总命中数,必须在totalHits.relation的上下文中解释
long numHits = totalHits.value;
//命中数是准确的 (EQUAL_TO) 还是总数的下限 (GREATER_THAN_OR_EQUAL_TO)
TotalHits.Relation relation = totalHits.relation;
float maxScore = hits.getMaxScore();

嵌套在 SearchHits 中的是可以迭代的划分开的具体搜索结果:

SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
    // do something with the SearchHit
}

2、实际案例中整合例子:

2.1、创建elasticsearch存储结构:

PUT imooc_news
{
  "mappings": {
    "properties": {
      "id":{
        "type": "keyword"
      },
      "title":{
        "type": "text"
      },
      "categoryId":{
        "type": "integer"
      },
      " articleType":{
        "type": "integer"
      },
      "articleCover":{
        "type": "keyword"
      },
      "isAppoint":{
        "type": "keyword"
      },
      "articleStatus":{
        "type": "integer"
      },
      "publishUserId":{
        "type": "keyword"
      },
      "publishTime":{
        "type": "date"
      },
      "readCounts":{
        "type": "integer"
      },
      "commentCounts":{
        "type": "integer"
      },
      "mongoFileId":{
        "type": "keyword"
      },
      "isDelete":{
        "type": "integer"
      },
      "createTime":{
        "type": "date"
      },
      "updateTime":{
        "type": "date"
      },
      "content":{
        "type": "text"
      }
    }
  }
}

2.2、配置方法

@Configuration
public class ElasticSearchConfig {
    public static final RequestOptions COMMON_OPTIONS;
    static {
        RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
/*        builder.addHeader("Authorization", "Bearer " + TOKEN);
        builder.setHttpAsyncResponseConsumerFactory(
                new HttpAsyncResponseConsumerFactory
                        .HeapBufferedResponseConsumerFactory(30 * 1024 * 1024 * 1024));*/
        COMMON_OPTIONS = builder.build();
    }

    @Bean
    public RestHighLevelClient restHighLevelClient() {
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(
                new HttpHost("192.168.111.131", 9200, "http")));
        return client;
    }
}

2.3、进行相关数据存储:

public void updateArticleStatus(String articleId, Integer status) throws IOException {
    Article article = new Article();
    article.setId(articleId);
    article.setArticleStatus(status);
    articleMapper.updateByPrimaryKeySelective(article);
    Article articleOne = articleMapper.selectByPrimaryKey(articleId);

    //ES官方推荐的一次bulk size介于5-15MB之间,请求个数是1000-5000个
    //BulkRequest bulkRequest = new BulkRequest();
    IndexRequest indexRequest = new IndexRequest(EsContant.PRODUCT_INDEX);
    indexRequest.id(articleOne.getId());
    String s = JSON.toJSONString(articleOne);
  //传入Json类型数据时必须设置XContentType.JSON indexRequest.source(s, XContentType.JSON);
//bulkRequest.add(indexRequest); IndexResponse index = restHighLevelClient.index(indexRequest, ElasticSearchConfig.COMMON_OPTIONS); }

 2.4、对数据进行查询:

@Override
    public PagedGridResult queryArticlePortalString(String keyword, Integer category, Integer page, Integer pageSize) throws IOException {
        //SearchSourceBuilder用于构建查询语句,所有跟操作都可以直接使用 SearchSourceBuilder的方法进
        //在本例中:{"query":{"bool":{"filter":[{"term":{"categoryId":{"value":11,"boost":1.0}}}],"adjust_pure_negative":true,"boost":1.0}}}
        //所以跟操作时query
        //总指elasticsearch查询核心在于对捋清楚条件的嵌套逻辑
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //进行模糊查询,由于要对title进行模糊查询,所以title的类型应该设置成text而不是keyword
        if (!StringUtils.isEmpty(keyword)) {
            boolQuery.must(QueryBuilders.matchQuery("title", keyword));
        }
        //根据category进行查找筛选
        if (!StringUtils.isEmpty(category)) {
            boolQuery.filter(QueryBuilders.termQuery("categoryId", category));
        }
        sourceBuilder.query(boolQuery);

        String s = sourceBuilder.toString();
System.out.println(
"构建DSL" + s);

     /** SearchRequest searchRequest = new SearchRequest();
      * searchRequest.indices("posts");
      * searchRequest.source(sourceBuilder);
      * 以下的方法相当于以上方法的结合体
     **/
SearchRequest searchRequest
= new SearchRequest(new String[]{EsContant.PRODUCT_INDEX}, sourceBuilder); /** * { * "took" : 3, * "timed_out" : false, * "_shards" : { * "total" : 1, * "successful" : 1, * "skipped" : 0, * "failed" : 0 * }, * "hits" : { * "total" : { * "value" : 1, * "relation" : "eq" * }, * "max_score" : 0.9105468, * "hits" : [ * { * "_index" : "imooc_news_dev", * "_type" : "_doc", * "_id" : "210510BTG8GFT8BC", * "_score" : 0.9105468, * "_source" : { * "articleCover" : "", * "articleStatus" : 4, * "articleType" : 2, * "categoryId" : 11, * "commentCounts" : 0, * "content" : ".......文章内容.......", * "createTime" : 1620635728000, * "id" : "210510BTG8GFT8BC", * "isAppoint" : 0, * "isDelete" : 0, * "publishTime" : 1620635728000, * "publishUserId" : "210509HK5HYTHZR4", * "readCounts" : 0, * "title" : "字节、腾讯、金山wps、跟谁学、百度 go工程师面试题集锦", * "updateTime" : 1620635728000 * } * } * ] * } * } */ // 2、执行检索 SearchResponse response = client.search(searchRequest, ElasticSearchConfig.COMMON_OPTIONS); SearchHits hits = response.getHits(); SearchHit[] newsHits = hits.getHits(); List<Article> articles = new ArrayList<>(); if (newsHits != null && newsHits.length > 0) { for (SearchHit newsHit : newsHits) { String sourceAsString = newsHit.getSourceAsString(); Article article = JSON.parseObject(sourceAsString, Article.class); articles.add(article); } } // PageHelper.startPage(page,pageSize); return setterPagedGrid(articles, page); }

 

以上是关于Elasticsearch整合SpringBoot案例的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot 整合 Elasticsearch 实现海量级数据搜索

Springboot 2.5.x整合ElasticSearch 7.1x

SpringBoot检索篇Ⅳ --- 整合ElasticSearch

SpringBoot整合ElasticSearch7.x及实战

[ ElasticSearch ] SpringBoot整合ElasticSearch

[ ElasticSearch ] SpringBoot整合ElasticSearch