ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring Boot整合elasticsearch7.15

2022-05-19 15:31:08  阅读:218  来源: 互联网

标签:INDEX Spring Boot sourceBuilder new elasticsearch7.15 elasticsearch org import


 

个人编写整合仅供参考!

出事概不负责!

 

此次整合的ES使用了ik分词器跟数据库配置同义词,ik分词器跟同义词可以查看本人其他文章有安装步骤。

程序可看下面的垃圾代码。

1.修改pom文件

<project>

    <dependencies>
    
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>${elastic.version}</version>
        </dependency>
        
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
            <version>${elastic.version}</version>
        </dependency>
        
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>${elastic.version}</version>
        </dependency>
        
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.11.1</version>
        </dependency>
        
    </dependencies>

    <properties>
        <elastic.version>7.15.0</elastic.version>
    </properties>
    
</project>

 

2.Controller

package com.xxx.web.controller.es;

import com.xxx.business.es.domain.vo.SearchVo;
import com.xxx.business.es.domain.vo.TitleVo;
import com.xxx.business.es.service.ContentService;
import com.xxx.business.keywordSubscription.domain.BKeywordSubscription;
import com.xxx.business.keywordSubscription.service.IBKeywordSubscriptionService;
import com.xxx.common.constant.HttpStatus;
import com.xxx.common.core.controller.BaseController;
import com.xxx.common.core.domain.AjaxResult;
import com.xxx.common.core.page.TableDataInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@RestController
@RequestMapping("/business/es")
public class ContentController extends BaseController {

@Autowired
private ContentService contentService;

@Autowired
private IBKeywordSubscriptionService ibKeywordSubscriptionService;

//同步所有用的
@PutMapping("/parse")
public AjaxResult parse() throws IOException {
return AjaxResult.success(contentService.parseContent());
}

//同步单个用的
@PutMapping("/parseOne/{ids}")
public AjaxResult parseOne(@PathVariable String[] ids) throws IOException {
return AjaxResult.success(contentService.parseContent(ids));
}

@GetMapping("/search")
public TableDataInfo search(SearchVo searchVo) throws IOException {
Map map = contentService.searchPageForHighlight(searchVo);
TableDataInfo rspData = new TableDataInfo();
rspData.setCode(HttpStatus.SUCCESS);
rspData.setMsg("查询成功");
List<TitleVo> listAll = (List<TitleVo>) map.get("listAll");
rspData.setRows(listAll);
Integer total = (Integer) map.get("total");
rspData.setTotal(total);
return rspData;
}
}

3.service

package com.xxx.business.es.service;


import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.xxx.business.es.domain.vo.SearchVo;
import com.xxx.business.es.domain.vo.TitleVo;
import com.xxx.business.title.mapper.BTitleMapper;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
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.client.indices.CreateIndexRequest;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
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.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.ruoyi.business.es.utils.CommonConstant.INDEX;
import static com.ruoyi.business.es.utils.CommonConstant.INDEX_O;


/**
* 业务编写
*/
@Service
public class ContentService {

@Autowired
private RestHighLevelClient restHighLevelClient;
@Autowired
private BTitleMapper bTitleMapper;

// 1. 解析数据放入到es索引当中
public Boolean parseContent() throws IOException {
//判断是否存在
GetIndexRequest getIndexRequest = new GetIndexRequest();
getIndexRequest.indices(INDEX);
Boolean exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
//如果存在就删除
if (exists) {
restHighLevelClient.indices().delete(new DeleteIndexRequest(INDEX), RequestOptions.DEFAULT);
}
String mappings = "{\n" +
" \"properties\": {\n" +
" \"name\": {\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_syno_max\",\n" +
" \"search_analyzer\": \"ik_syno\"\n" +
" },\n" +
" \"title\": {\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_max_word\",\n" +
" \"search_analyzer\": \"ik_smart\"\n" +
" }\n" +
" }\n" +
" }";
String settings = "{\n" +
" \"number_of_shards\": 1,\n" +
" \"number_of_replicas\": 0,\n" +
" \"index\": {\n" +
" \"analysis\": {\n" +
" \"filter\": {\n" +
" \"mysql_synonym\": {\n" +
" \"type\": \"dynamic_synonym\",\n" +
" \"synonyms_path\": \"fromMySql\",\n" +
" \"interval\": 30\n" +
" }\n" +
" },\n" +
" \"analyzer\": {\n" +
" \"ik_syno\": {\n" +
" \"type\": \"custom\",\n" +
" \"tokenizer\": \"ik_smart\",\n" +
" \"filter\": [\n" +
" \"mysql_synonym\"\n" +
" ]\n" +
" },\n" +
" \"ik_syno_max\": {\n" +
" \"type\": \"custom\",\n" +
" \"tokenizer\": \"ik_max_word\",\n" +
" \"filter\": [\n" +
" \"mysql_synonym\"\n" +
" ]\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
" }";
try {
CreateIndexRequest request = new CreateIndexRequest(INDEX);
request.settings(settings, XContentType.JSON);
request.mapping(mappings, XContentType.JSON);
//创建索引
restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
} catch (Exception e) {
e.printStackTrace();
}
//下面这个list是查询标题的 然后添加到es里
List<TitleVo> contents = bTitleMapper.selectTitleList();
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("200m");
for (int i = 0; i < contents.size(); i++) {
bulkRequest.add(new IndexRequest(INDEX, "_doc", i + "").source(JSON.toJSONString(contents.get(i)), XContentType.JSON));
}

BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
return !bulk.hasFailures();
}

public Boolean parseContent(String[] ids) throws IOException {
//下面这个list是查询标题的 然后添加到es里
List<TitleVo> contents = bTitleMapper.selectTitleListById(ids);
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("200m");
for (int i = 0; i < contents.size(); i++) {
TitleVo titleVo = contents.get(i);
String id1 = titleVo.getId();
GetIndexRequest getIndexRequest = new GetIndexRequest();
getIndexRequest.indices(INDEX);
Boolean exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
SearchRequest searchRequest = null;
if (exists) {
searchRequest = new SearchRequest(INDEX);
} else {
searchRequest = new SearchRequest(INDEX_O);
}
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
sourceBuilder.size(10000);
boolQueryBuilder.must(new MatchQueryBuilder("id", id1));
sourceBuilder.query(boolQueryBuilder);
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hits = searchResponse.getHits().getHits();
if (hits.length == 0) {
SearchSourceBuilder sourceBuilder1 = new SearchSourceBuilder();
SearchRequest searchRequest1 = new SearchRequest(INDEX);
sourceBuilder1.size(10000);
sourceBuilder1.searchAfter();
searchRequest1.source(sourceBuilder1);
SearchResponse searchResponse1 = restHighLevelClient.search(searchRequest1, RequestOptions.DEFAULT);
int length = searchResponse1.getHits().getHits().length;
bulkRequest.add(new IndexRequest(INDEX, "_doc", length + 1 + "").source(JSON.toJSONString(contents.get(i)), XContentType.JSON));
} else {
String id = hits[0].getId();
bulkRequest.add(new IndexRequest(INDEX, "_doc", id + "").source(JSON.toJSONString(contents.get(i)), XContentType.JSON));
}
}

BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
return !bulk.hasFailures();
}

// 2. 查询这些数据实现搜索功能
public Map searchPageForHighlight(SearchVo searchVo) throws IOException {
String keywords = searchVo.getKeywords();
String dataSourceType = searchVo.getDataSourceType();
String id = searchVo.getId();
int pageNo = searchVo.getPageNum();
int pageSize = searchVo.getPageSize();
if (pageNo <= 1) {
pageNo = 0;
}
if (pageNo != 0) {
pageNo = pageNo * pageSize - pageSize;
}
List<TitleVo> listAll = new ArrayList<>();
int total = 0;
if (!ObjectUtils.isEmpty(dataSourceType) && !dataSourceType.equals("001")) {
// 条件搜索
GetIndexRequest getIndexRequest = new GetIndexRequest();
getIndexRequest.indices(INDEX);
Boolean exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
SearchRequest searchRequest = null;
SearchRequest searchRequest1 = null;
if (exists) {
searchRequest = new SearchRequest(INDEX);
searchRequest1 = new SearchRequest(INDEX);
} else {
searchRequest = new SearchRequest(INDEX_O);
searchRequest1 = new SearchRequest(INDEX_O);
}
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
SearchSourceBuilder sourceBuilder1 = new SearchSourceBuilder();
sourceBuilder1.size(10000);
// 分页
if (pageSize != 0) {
sourceBuilder.from(pageNo);
sourceBuilder.size(pageSize);
}
BoolQueryBuilder boolQueryBuilder5 = new BoolQueryBuilder();
boolean keywordsEmpty = ObjectUtils.isEmpty(keywords);
boolean idEmpty = ObjectUtils.isEmpty(id);
if (exists) {
if (!idEmpty) {
boolQueryBuilder5.must(new MatchQueryBuilder("id", id));
// 当前下面这个相当于mysql中where条件 a=8 and (b=3 or b=4)
boolQueryBuilder5.must(QueryBuilders.boolQuery().should(QueryBuilders.wildcardQuery("ancestors", "*" + dataSourceType + "*")).should(new MatchQueryBuilder("dataSourceType", dataSourceType)));
sourceBuilder.query(boolQueryBuilder5);
sourceBuilder1.query(boolQueryBuilder5);
} else if (!keywordsEmpty) {
boolQueryBuilder5.must(new MatchQueryBuilder("title", keywords));
// 当前下面这个相当于mysql中where条件 a=8 and (b=3 or b=4)
boolQueryBuilder5.must(QueryBuilders.boolQuery().should(QueryBuilders.wildcardQuery("ancestors", "*" + dataSourceType + "*")).should(new MatchQueryBuilder("dataSourceType", dataSourceType)));
sourceBuilder.query(boolQueryBuilder5);
sourceBuilder1.query(boolQueryBuilder5);
} else {
// 当前下面这个相当于mysql中where条件 a=8 and (b=3 or b=4)
boolQueryBuilder5.must(QueryBuilders.boolQuery().should(QueryBuilders.wildcardQuery("ancestors", "*" + dataSourceType + "*")).should(new MatchQueryBuilder("dataSourceType", dataSourceType)));
sourceBuilder.query(boolQueryBuilder5);
sourceBuilder1.query(boolQueryBuilder5);
}
}
// 高亮
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("title");
highlightBuilder.requireFieldMatch(false); // 多个高亮显示!
highlightBuilder.preTags("<span style='color:red'>");
highlightBuilder.postTags("</span>");
sourceBuilder.highlighter(highlightBuilder);
sourceBuilder.searchAfter();
if (exists) {
if (!idEmpty) {
sourceBuilder.sort("_score", SortOrder.DESC); //排序
sourceBuilder.sort("dataSourceType", SortOrder.DESC); //排序
} else if (!keywordsEmpty) {
sourceBuilder.sort("_score", SortOrder.DESC); //排序
sourceBuilder.sort("dataSourceType", SortOrder.DESC); //排序
} else {
sourceBuilder.sort("dataSourceType", SortOrder.DESC); //排序
}
}
// 执行搜索
searchRequest.source(sourceBuilder);
searchRequest1.source(sourceBuilder1);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchResponse searchResponse1 = restHighLevelClient.search(searchRequest1, RequestOptions.DEFAULT);
// 解析结果
for (SearchHit documentField : searchResponse.getHits().getHits()) {
Map<String, HighlightField> highlightFields = documentField.getHighlightFields();
HighlightField title = highlightFields.get("title");
Map<String, Object> sourceAsMap = documentField.getSourceAsMap(); // 原来的结果
// 解析高亮的字段, 将原来的字段换为我们高亮的字段即可!
if (title != null) {
Text[] fragments = title.fragments();
String n_title = "";
for (Text text : fragments) {
n_title += text;
}
sourceAsMap.put("title", n_title);
}
listAll.add(JSONUtil.toBean(JSONUtil.toJsonStr(sourceAsMap), TitleVo.class));
}
int length = searchResponse1.getHits().getHits().length;
total += length;
} else {
// 条件搜索
GetIndexRequest getIndexRequest = new GetIndexRequest();
getIndexRequest.indices(INDEX);
Boolean exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
SearchRequest searchRequest = null;
SearchRequest searchRequest1 = null;
if (exists) {
searchRequest = new SearchRequest(INDEX);
searchRequest1 = new SearchRequest(INDEX);
} else {
searchRequest = new SearchRequest(INDEX_O);
searchRequest1 = new SearchRequest(INDEX_O);
}
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
SearchSourceBuilder sourceBuilder1 = new SearchSourceBuilder();
sourceBuilder1.size(10000);
// 分页
if (pageSize != 0) {
sourceBuilder.from(pageNo);
sourceBuilder.size(pageSize);
}
BoolQueryBuilder boolQueryBuilder5 = new BoolQueryBuilder();
boolean keywordsEmpty = ObjectUtils.isEmpty(keywords);
boolean idEmpty = ObjectUtils.isEmpty(id);
if (!idEmpty && exists) {
boolQueryBuilder5.must(new MatchQueryBuilder("id", id));
sourceBuilder.query(boolQueryBuilder5);

sourceBuilder1.query(boolQueryBuilder5);

} else if (!keywordsEmpty && exists) {
boolQueryBuilder5.must(new MatchQueryBuilder("title", keywords));
sourceBuilder.query(boolQueryBuilder5);
sourceBuilder1.query(boolQueryBuilder5);
} else {
sourceBuilder.query(QueryBuilders.matchAllQuery());
sourceBuilder1.query(QueryBuilders.matchAllQuery());
}
// 高亮
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("title");
highlightBuilder.requireFieldMatch(false); // 多个高亮显示!
highlightBuilder.preTags("<span style='color:red'>");
highlightBuilder.postTags("</span>");
sourceBuilder.highlighter(highlightBuilder);
sourceBuilder.searchAfter();
sourceBuilder1.searchAfter();
if (exists) {
if (!idEmpty) {
sourceBuilder.sort("_score", SortOrder.DESC); //排序
sourceBuilder.sort("dataSourceType", SortOrder.DESC); //排序
} else if (!keywordsEmpty) {
sourceBuilder.sort("_score", SortOrder.DESC); //排序
sourceBuilder.sort("dataSourceType", SortOrder.DESC); //排序
} else {
sourceBuilder.sort("dataSourceType", SortOrder.DESC); //排序
}
}
// 执行搜索
searchRequest.source(sourceBuilder);
searchRequest1.source(sourceBuilder1);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchResponse searchResponse1 = restHighLevelClient.search(searchRequest1, RequestOptions.DEFAULT);
// 解析结果
for (SearchHit documentField : searchResponse.getHits().getHits()) {
Map<String, HighlightField> highlightFields = documentField.getHighlightFields();
HighlightField title = highlightFields.get("title");
Map<String, Object> sourceAsMap = documentField.getSourceAsMap(); // 原来的结果
// 解析高亮的字段, 将原来的字段换为我们高亮的字段即可!
if (title != null) {
Text[] fragments = title.fragments();
String n_title = "";
for (Text text : fragments) {
n_title += text;
}
sourceAsMap.put("title", n_title);
}
listAll.add(JSONUtil.toBean(JSONUtil.toJsonStr(sourceAsMap), TitleVo.class));
}
total += searchResponse1.getHits().getHits().length;
}

Map map = new HashMap();
map.put("listAll", listAll);
map.put("total", total);
return map;
}
}

4.utils

package com.xxx.business.es.utils;

public class CommonConstant {
//es的index不能有大写 必须为小写
public static final String INDEX = "buuindex";
public static final String INDEX_O = "buuindex1";
}

5.config

package com.xxx.web.core.config;

import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ElasticSearchClientConfig {
    public static RestHighLevelClient client = null;

    /**
     * 是否使用密码
     */
    @Value("${elasticSearch.enabled}")
    private boolean enabled;

    /**
     * 访问方式
     */
    @Value("${elasticSearch.scheme}")
    private String scheme;
    /**
     * 地址
     */
    @Value("${elasticSearch.hostname}")
    private String hostname;
    /**
     * 端口
     */
    @Value("${elasticSearch.port}")
    private Integer port;
    /**
     * 登录账户
     */
    @Value("${elasticSearch.userName}")
    private String userName;
    /**
     * 登录密码
     */
    @Value("${elasticSearch.password}")
    private String password;

    @Bean
    public RestHighLevelClient restHighLevelClient() {
        if (enabled) {
            //需要密码进行访问
            final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
            credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
            RestClientBuilder restClientBuilder = RestClient.builder(
                            new HttpHost(hostname, port, scheme)
                    )
                    .setHttpClientConfigCallback(httpAsyncClientBuilder -> httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider));
            client = new RestHighLevelClient(restClientBuilder);
        } else {
            //不需要密码就可以访问
            client = new RestHighLevelClient(
                    RestClient.builder(
                            new HttpHost(hostname, port, scheme)
                    )
            );
        }
        return client;
    }


}

6,application.yml

  # es配置
elasticSearch:
  # 是否需要密码访问
  enabled: true
  # 访问方式
  scheme: http
  # 地址
  hostname: 127.0.0.1
  #端口
  port: 9200
  #用户名
  userName: elastic
  #密码
  password: XXXXXX

 

标签:INDEX,Spring,Boot,sourceBuilder,new,elasticsearch7.15,elasticsearch,org,import
来源: https://www.cnblogs.com/shiheng01/p/16288685.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有