Compare commits

...

1 Commits

Author SHA1 Message Date
mf-xuao 4b0250aa6b first commit jdk 8版本 4 weeks ago

@ -130,21 +130,9 @@
<artifactId>hutool-all</artifactId> <artifactId>hutool-all</artifactId>
</dependency> </dependency>
<!-- es--> <!-- es-->
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.elasticsearch.client</groupId> <groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId> <artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>
<dependency>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.parsson</groupId>
<artifactId>parsson</artifactId>
</dependency> </dependency>
<!-- gson--> <!-- gson-->
<dependency> <dependency>

@ -1,9 +1,5 @@
package com.hongshu.common.config.es; package com.hongshu.common.config.es;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost; import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope; import org.apache.http.auth.AuthScope;
@ -11,6 +7,8 @@ import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider; import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient; 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.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -36,42 +34,29 @@ public class ESConfig {
@Value("${es.password}") @Value("${es.password}")
String password; String password;
private RestClient restClient; private RestHighLevelClient client;
private ElasticsearchClient client;
private ElasticsearchTransport transport;
@Bean(name = "elasticsearchClient") @Bean(name = "elasticsearchClient")
public ElasticsearchClient getElasticsearchClient() { public RestHighLevelClient getElasticsearchClient() {
// 设置用户名和密码 // 设置用户名和密码
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password)); credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
// 创建带有基本身份验证的 RestClient // 创建带有基本身份验证的 RestClient
restClient = RestClient.builder( RestClientBuilder builder = RestClient.builder(new HttpHost(esUrl, esPort))
new HttpHost(esUrl, esPort)
)
.setHttpClientConfigCallback(httpClientBuilder -> .setHttpClientConfigCallback(httpClientBuilder ->
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider) httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)
) );
.build();
// 使用 Jackson 映射器创建传输层
transport = new RestClientTransport(
restClient, new JacksonJsonpMapper()
);
// 创建 API 客户端 // 创建 API 客户端
client = new ElasticsearchClient(transport); client = new RestHighLevelClient(builder);
return client; return client;
} }
public void close() { public void close() {
if (client != null) { if (client != null) {
try { try {
transport.close(); client.close();
restClient.close();
} catch (IOException e) { } catch (IOException e) {
log.error("关闭es连接异常"); log.error("关闭es连接异常");
} }

@ -1,9 +1,7 @@
package com.hongshu.web.service.impl; package com.hongshu.web.service.impl;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import co.elastic.clients.elasticsearch.ElasticsearchClient; import com.alibaba.fastjson2.JSON;
import co.elastic.clients.elasticsearch.core.GetResponse;
import co.elastic.clients.elasticsearch.core.UpdateResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hongshu.common.constant.NoteConstant; import com.hongshu.common.constant.NoteConstant;
@ -20,6 +18,12 @@ import com.hongshu.web.mapper.WebUserMapper;
import com.hongshu.web.mapper.WebUserNoteRelationMapper; import com.hongshu.web.mapper.WebUserNoteRelationMapper;
import com.hongshu.web.service.IWebBrowseRecordService; import com.hongshu.web.service.IWebBrowseRecordService;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -44,7 +48,7 @@ public class WebBrowseRecordServiceImpl extends ServiceImpl<WebNoteMapper, WebNo
@Autowired @Autowired
private WebLikeOrCollectMapper likeOrCollectionMapper; private WebLikeOrCollectMapper likeOrCollectionMapper;
@Autowired @Autowired
private ElasticsearchClient elasticsearchClient; private RestHighLevelClient restHighLevelClient;
/** /**
@ -118,21 +122,18 @@ public class WebBrowseRecordServiceImpl extends ServiceImpl<WebNoteMapper, WebNo
private void updateEsNote(BrowseRecordDTO browseRecordDTO) { private void updateEsNote(BrowseRecordDTO browseRecordDTO) {
try { try {
// Step 1: 获取现有的数据 // Step 1: 获取现有的数据
GetResponse<NoteSearchVO> getResponse = elasticsearchClient.get(g -> GetRequest getRequest = new GetRequest(NoteConstant.NOTE_INDEX, browseRecordDTO.getNid());
g.index(NoteConstant.NOTE_INDEX) GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
.id(browseRecordDTO.getNid()),
NoteSearchVO.class);
// 检查是否获取到了数据 // 检查是否获取到了数据
if (getResponse.found()) { if (getResponse.isExists()) {
NoteSearchVO noteSearchVo = getResponse.source(); NoteSearchVO noteSearchVo = JSON.parseObject(getResponse.getSourceAsString(), NoteSearchVO.class);
// Step 2: 更新 viewCount 字段 // Step 2: 更新 viewCount 字段
noteSearchVo.setViewCount(noteSearchVo.getViewCount() + 1); noteSearchVo.setViewCount(noteSearchVo.getViewCount() + 1);
// Step 3: 将更新后的数据保存回 Elasticsearch // Step 3: 将更新后的数据保存回 Elasticsearch
UpdateResponse<NoteSearchVO> updateResponse = elasticsearchClient.update(u -> UpdateRequest updateRequest = new UpdateRequest(NoteConstant.NOTE_INDEX, browseRecordDTO.getNid())
u.index(NoteConstant.NOTE_INDEX) .doc(JSON.toJSONString(noteSearchVo), XContentType.JSON);
.id(browseRecordDTO.getNid()) restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
.doc(noteSearchVo),
NoteSearchVO.class);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -158,4 +159,4 @@ public class WebBrowseRecordServiceImpl extends ServiceImpl<WebNoteMapper, WebNo
userNoteRelationMapper.deleteBatchIds(idsToDelete); userNoteRelationMapper.deleteBatchIds(idsToDelete);
} }
} }
} }

@ -1,14 +1,7 @@
package com.hongshu.web.service.impl; package com.hongshu.web.service.impl;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import co.elastic.clients.elasticsearch.ElasticsearchClient; import com.alibaba.fastjson2.JSON;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch.core.*;
import co.elastic.clients.elasticsearch.core.bulk.BulkOperation;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.elasticsearch.core.search.TotalHits;
import co.elastic.clients.elasticsearch.indices.CreateIndexRequest;
import co.elastic.clients.elasticsearch.indices.DeleteIndexRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -32,6 +25,26 @@ import com.hongshu.web.service.IWebEsNoteService;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.client.indices.CreateIndexRequest;
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.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -54,7 +67,7 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
@Autowired @Autowired
private WebNoteMapper noteMapper; private WebNoteMapper noteMapper;
@Autowired @Autowired
private ElasticsearchClient elasticsearchClient; private RestHighLevelClient restHighLevelClient;
@Autowired @Autowired
private WebLikeOrCollectMapper likeOrCollectionMapper; private WebLikeOrCollectMapper likeOrCollectionMapper;
@ -71,40 +84,48 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
Page<NoteSearchVO> page = new Page<>(); Page<NoteSearchVO> page = new Page<>();
List<NoteSearchVO> noteSearchVOList = new ArrayList<>(); List<NoteSearchVO> noteSearchVOList = new ArrayList<>();
try { try {
SearchRequest.Builder builder = new SearchRequest.Builder().index(NoteConstant.NOTE_INDEX); SearchRequest searchRequest = new SearchRequest(NoteConstant.NOTE_INDEX);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder mainQuery = QueryBuilders.boolQuery();
if (StringUtils.isNotBlank(esNoteDTO.getKeyword())) { if (StringUtils.isNotBlank(esNoteDTO.getKeyword())) {
builder.query(q -> q.bool(b -> b BoolQueryBuilder keywordQuery = QueryBuilders.boolQuery()
.should(h -> h.match(f -> f.field("title").boost(1f).query(esNoteDTO.getKeyword()))) .should(QueryBuilders.matchQuery("title", esNoteDTO.getKeyword()).boost(1f))
.should(h -> h.match(f -> f.field("username").boost(0.5f).query(esNoteDTO.getKeyword()))) .should(QueryBuilders.matchQuery("username", esNoteDTO.getKeyword()).boost(0.5f))
.should(h -> h.match(f -> f.field("content").boost(1f).query(esNoteDTO.getKeyword()))) .should(QueryBuilders.matchQuery("content", esNoteDTO.getKeyword()).boost(1f))
.should(h -> h.match(f -> f.field("tags").boost(4f).query(esNoteDTO.getKeyword()))) .should(QueryBuilders.matchQuery("tags", esNoteDTO.getKeyword()).boost(4f))
.should(h -> h.match(f -> f.field("categoryName").boost(2f).query(esNoteDTO.getKeyword()))) .should(QueryBuilders.matchQuery("categoryName", esNoteDTO.getKeyword()).boost(2f))
.should(h -> h.match(f -> f.field("categoryParentName").boost(1.5f).query(esNoteDTO.getKeyword()))) .should(QueryBuilders.matchQuery("categoryParentName", esNoteDTO.getKeyword()).boost(1.5f));
)); mainQuery.must(keywordQuery);
} }
if (StringUtils.isNotBlank(esNoteDTO.getCpid()) && StringUtils.isNotBlank(esNoteDTO.getCid())) { if (StringUtils.isNotBlank(esNoteDTO.getCpid()) && StringUtils.isNotBlank(esNoteDTO.getCid())) {
builder.query(q -> q.bool(b -> b mainQuery.must(QueryBuilders.matchQuery("cid", esNoteDTO.getCid()))
.must(h -> h.match(m -> m.field("cid").query(esNoteDTO.getCid()))) .must(QueryBuilders.matchQuery("cpid", esNoteDTO.getCpid()));
.must(h -> h.match(m -> m.field("cpid").query(esNoteDTO.getCpid())))
));
} else if (StringUtils.isNotBlank(esNoteDTO.getCpid())) { } else if (StringUtils.isNotBlank(esNoteDTO.getCpid())) {
builder.query(h -> h.match(m -> m.field("cpid").query(esNoteDTO.getCpid()))); mainQuery.must(QueryBuilders.matchQuery("cpid", esNoteDTO.getCpid()));
}
if (mainQuery.hasClauses()) {
sourceBuilder.query(mainQuery);
} }
if (esNoteDTO.getType() == 1) { if (esNoteDTO.getType() == 1) {
builder.sort(o -> o.field(f -> f.field("likeCount").order(SortOrder.Desc))); sourceBuilder.sort("likeCount", SortOrder.DESC);
} else if (esNoteDTO.getType() == 2) { } else if (esNoteDTO.getType() == 2) {
builder.sort(o -> o.field(f -> f.field("time").order(SortOrder.Desc))); sourceBuilder.sort("time", SortOrder.DESC);
} }
builder.from((int) (currentPage - 1) * (int) pageSize);
builder.size((int) pageSize); sourceBuilder.from((int) (currentPage - 1) * (int) pageSize);
SearchRequest searchRequest = builder.build(); sourceBuilder.size((int) pageSize);
SearchResponse<NoteSearchVO> searchResponse = elasticsearchClient.search(searchRequest, NoteSearchVO.class); searchRequest.source(sourceBuilder);
TotalHits totalHits = searchResponse.hits().total();
page.setTotal(Objects.requireNonNull(totalHits).value()); SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
List<Hit<NoteSearchVO>> hits = searchResponse.hits().hits(); long totalHits = searchResponse.getHits().getTotalHits().value;
for (Hit<NoteSearchVO> hit : hits) { page.setTotal(totalHits);
NoteSearchVO noteSearchVo = hit.source();
for (SearchHit hit : searchResponse.getHits().getHits()) {
NoteSearchVO noteSearchVo = JSON.parseObject(hit.getSourceAsString(), NoteSearchVO.class);
noteSearchVOList.add(noteSearchVo); noteSearchVOList.add(noteSearchVo);
} }
} catch (Exception e) { } catch (Exception e) {
@ -139,23 +160,25 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
List<NoteSearchVO> noteSearchVOList = new ArrayList<>(); List<NoteSearchVO> noteSearchVOList = new ArrayList<>();
//得到当前用户的浏览记录 //得到当前用户的浏览记录
try { try {
SearchRequest.Builder builder = new SearchRequest.Builder().index(NoteConstant.NOTE_INDEX); SearchRequest searchRequest = new SearchRequest(NoteConstant.NOTE_INDEX);
builder.size(1000); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
SearchRequest searchRequest = builder.build(); sourceBuilder.size(1000);
SearchResponse<NoteSearchVO> searchResponse = elasticsearchClient.search(searchRequest, NoteSearchVO.class); searchRequest.source(sourceBuilder);
TotalHits totalHits = searchResponse.hits().total();
//得到所有的数据 SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
List<Hit<NoteSearchVO>> hits = searchResponse.hits().hits(); long totalHits = searchResponse.getHits().getTotalHits().value;
if (CollectionUtil.isNotEmpty(hits)) {
for (Hit<NoteSearchVO> hit : hits) { SearchHit[] hits = searchResponse.getHits().getHits();
NoteSearchVO noteSearchVo = hit.source(); if (hits.length > 0) {
for (SearchHit hit : hits) {
NoteSearchVO noteSearchVo = JSON.parseObject(hit.getSourceAsString(), NoteSearchVO.class);
noteSearchVOList.add(noteSearchVo); noteSearchVOList.add(noteSearchVo);
} }
Collections.shuffle(noteSearchVOList); Collections.shuffle(noteSearchVOList);
List<List<NoteSearchVO>> partition = Lists.partition(noteSearchVOList, (int) pageSize); List<List<NoteSearchVO>> partition = Lists.partition(noteSearchVOList, (int) pageSize);
List<NoteSearchVO> noteSearchVOS = partition.get((int) currentPage - 1); List<NoteSearchVO> noteSearchVOS = partition.get((int) currentPage - 1);
page.setTotal(totalHits != null ? totalHits.value() : 0); page.setTotal(totalHits);
page.setRecords(noteSearchVOS); page.setRecords(noteSearchVOS);
} }
} catch (Exception e) { } catch (Exception e) {
@ -176,15 +199,19 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
Page<WebUser> page = new Page<>(); Page<WebUser> page = new Page<>();
String userId = WebUtils.getRequestHeader(UserConstant.USER_ID); String userId = WebUtils.getRequestHeader(UserConstant.USER_ID);
// 用户ID为空 默认随机加载100条数据 // 用户ID为空 默认随机加载100条数据
List<WebUser> recommendList = null; List<WebUser> recommendList = new ArrayList<>();
if (StringUtils.isBlank(userId)) { if (StringUtils.isBlank(userId)) {
SearchRequest searchRequest = SearchRequest.of(s -> s SearchRequest searchRequest = new SearchRequest(NoteConstant.NOTE_INDEX);
.index(NoteConstant.NOTE_INDEX) SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
.size(100)); sourceBuilder.size(100);
SearchResponse<WebUser> searchResponse = elasticsearchClient.search(searchRequest, WebUser.class); searchRequest.source(sourceBuilder);
recommendList = searchResponse.hits().hits().stream()
.map(Hit::source) SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
.collect(Collectors.toList());
for (SearchHit hit : searchResponse.getHits().getHits()) {
WebUser user = JSON.parseObject(hit.getSourceAsString(), WebUser.class);
recommendList.add(user);
}
// 随机排序 // 随机排序
Collections.shuffle(recommendList, new Random()); Collections.shuffle(recommendList, new Random());
} else { } else {
@ -198,6 +225,7 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
page.setRecords(Collections.emptyList()); page.setRecords(Collections.emptyList());
return page; return page;
} }
List<WebUser> userList = partition.get((int) currentPage - 1); List<WebUser> userList = partition.get((int) currentPage - 1);
page.setTotal(recommendList.size()); page.setTotal(recommendList.size());
page.setRecords(userList); page.setRecords(userList);
@ -216,35 +244,29 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
List<NoteSearchVO> noteSearchVOList = new ArrayList<>(); List<NoteSearchVO> noteSearchVOList = new ArrayList<>();
try { try {
// 构建搜索请求 SearchRequest searchRequest = new SearchRequest(NoteConstant.NOTE_INDEX);
SearchRequest.Builder builder = new SearchRequest.Builder() SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
.index(NoteConstant.NOTE_INDEX) sourceBuilder.from(Math.toIntExact((currentPage - 1) * pageSize));
.from(Math.toIntExact((currentPage - 1) * pageSize)) // 设置分页起始点 sourceBuilder.size(Math.toIntExact(pageSize));
.size(Math.toIntExact(pageSize)) // 设置分页大小 sourceBuilder.sort("likeCount", SortOrder.DESC);
.sort(s -> s.field(f -> f.field("likeCount").order(SortOrder.Desc))); // 按 likeCount 降序排序 searchRequest.source(sourceBuilder);
SearchRequest searchRequest = builder.build(); SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
long totalHits = searchResponse.getHits().getTotalHits().value;
// 执行搜索请求
SearchResponse<NoteSearchVO> searchResponse = elasticsearchClient.search(searchRequest, NoteSearchVO.class); SearchHit[] hits = searchResponse.getHits().getHits();
TotalHits totalHits = searchResponse.hits().total(); if (hits.length > 0) {
for (SearchHit hit : hits) {
// 获取搜索结果 NoteSearchVO noteSearchVo = JSON.parseObject(hit.getSourceAsString(), NoteSearchVO.class);
List<Hit<NoteSearchVO>> hits = searchResponse.hits().hits();
if (CollectionUtil.isNotEmpty(hits)) {
for (Hit<NoteSearchVO> hit : hits) {
NoteSearchVO noteSearchVo = hit.source();
noteSearchVOList.add(noteSearchVo); noteSearchVOList.add(noteSearchVo);
} }
} }
// 设置分页结果 page.setTotal(totalHits);
page.setTotal(totalHits != null ? totalHits.value() : 0);
page.setRecords(noteSearchVOList); page.setRecords(noteSearchVOList);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
// 这里可以进一步处理异常,比如记录日志或者抛出自定义异常
} }
return page; return page;
} }
@ -257,8 +279,11 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
@Override @Override
public void addNote(NoteSearchVO noteSearchVo) { public void addNote(NoteSearchVO noteSearchVo) {
try { try {
CreateResponse createResponse = elasticsearchClient.create(e -> e.index(NoteConstant.NOTE_INDEX).id(noteSearchVo.getId()).document(noteSearchVo)); IndexRequest indexRequest = new IndexRequest(NoteConstant.NOTE_INDEX)
log.info("createResponse.result{}", createResponse.result()); .id(noteSearchVo.getId())
.source(JSON.toJSONString(noteSearchVo), XContentType.JSON);
IndexResponse indexResponse = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
log.info("indexResponse.result{}", indexResponse.getResult());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -272,8 +297,10 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
@Override @Override
public void updateNote(NoteSearchVO noteSearchVo) { public void updateNote(NoteSearchVO noteSearchVo) {
try { try {
UpdateResponse<NoteSearchVO> updateResponse = elasticsearchClient.update(e -> e.index(NoteConstant.NOTE_INDEX).id(noteSearchVo.getId()).doc(noteSearchVo), NoteSearchVO.class); UpdateRequest updateRequest = new UpdateRequest(NoteConstant.NOTE_INDEX, noteSearchVo.getId())
log.info("updateResponse.result() = " + updateResponse.result()); .doc(JSON.toJSONString(noteSearchVo), XContentType.JSON);
UpdateResponse updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
log.info("updateResponse.result() = " + updateResponse.getResult());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -287,8 +314,9 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
@Override @Override
public void deleteNote(String noteId) { public void deleteNote(String noteId) {
try { try {
DeleteResponse deleteResponse = elasticsearchClient.delete(e -> e.index(NoteConstant.NOTE_INDEX).id(String.valueOf(noteId))); DeleteRequest deleteRequest = new DeleteRequest(NoteConstant.NOTE_INDEX, String.valueOf(noteId));
log.info("deleteResponse.result() ={} ", deleteResponse.result()); DeleteResponse deleteResponse = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
log.info("deleteResponse.result() ={} ", deleteResponse.getResult());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -316,13 +344,15 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
noteSearchVo.setIsLike(likeOrCollectionIds.contains(noteSearchVo.getId())); noteSearchVo.setIsLike(likeOrCollectionIds.contains(noteSearchVo.getId()));
} }
try { try {
List<BulkOperation> result = new ArrayList<>(); BulkRequest bulkRequest = new BulkRequest();
for (NoteSearchVO noteSearchVo : noteSearchVOList) { for (NoteSearchVO noteSearchVo : noteSearchVOList) {
result.add(new BulkOperation.Builder().create( IndexRequest indexRequest = new IndexRequest(NoteConstant.NOTE_INDEX)
d -> d.document(noteSearchVo).id(noteSearchVo.getId()).index(NoteConstant.NOTE_INDEX)).build()); .id(noteSearchVo.getId())
.source(JSON.toJSONString(noteSearchVo), XContentType.JSON);
bulkRequest.add(indexRequest);
} }
BulkResponse bulkResponse = elasticsearchClient.bulk(e -> e.index(NoteConstant.NOTE_INDEX).operations(result)); BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
log.info("createResponse.result{}", bulkResponse.toString()); log.info("createResponse.result{}", bulkResponse.hasFailures() ? "has failures" : "success");
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -335,16 +365,19 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
public void delNoteBulkData() { public void delNoteBulkData() {
try { try {
// 删除索引 // 删除索引
DeleteIndexRequest deleteIndexRequest = DeleteIndexRequest.of(builder -> builder.index(NoteConstant.NOTE_INDEX)); DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(NoteConstant.NOTE_INDEX);
elasticsearchClient.indices().delete(deleteIndexRequest); restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
log.info("删除索引:{}", NoteConstant.NOTE_INDEX); log.info("删除索引:{}", NoteConstant.NOTE_INDEX);
} catch (Exception e) {
log.error("删除索引异常 (可能不存在): {}", NoteConstant.NOTE_INDEX);
}
try {
// 重新创建索引 // 重新创建索引
CreateIndexRequest createIndexRequest = CreateIndexRequest.of(builder -> builder.index(NoteConstant.NOTE_INDEX)); CreateIndexRequest createIndexRequest = new CreateIndexRequest(NoteConstant.NOTE_INDEX);
elasticsearchClient.indices().create(createIndexRequest); restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
log.info("创建索引:{}", NoteConstant.NOTE_INDEX); log.info("创建索引:{}", NoteConstant.NOTE_INDEX);
} catch (Exception e) { } catch (Exception e) {
log.error("Error occurred while deleting and recreating index: {}", NoteConstant.NOTE_INDEX, e); log.error("Error occurred while creating index: {}", NoteConstant.NOTE_INDEX, e);
} }
} }

@ -1,17 +1,32 @@
package com.hongshu.web.service.impl; package com.hongshu.web.service.impl;
import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.RandomUtil;
import co.elastic.clients.elasticsearch.ElasticsearchClient; import com.alibaba.fastjson2.JSON;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch.core.*;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.transport.endpoints.BooleanResponse;
import com.hongshu.common.constant.NoteConstant; import com.hongshu.common.constant.NoteConstant;
import com.hongshu.web.domain.dto.EsRecordDTO; import com.hongshu.web.domain.dto.EsRecordDTO;
import com.hongshu.web.domain.vo.RecordSearchVO; import com.hongshu.web.domain.vo.RecordSearchVO;
import com.hongshu.web.service.IWebEsRecordService; import com.hongshu.web.service.IWebEsRecordService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -28,8 +43,7 @@ import java.util.List;
public class WebEsRecordServiceImpl implements IWebEsRecordService { public class WebEsRecordServiceImpl implements IWebEsRecordService {
@Autowired @Autowired
ElasticsearchClient elasticsearchClient; private RestHighLevelClient restHighLevelClient;
/** /**
* *
@ -41,35 +55,39 @@ public class WebEsRecordServiceImpl implements IWebEsRecordService {
List<RecordSearchVO> records = new ArrayList<>(); List<RecordSearchVO> records = new ArrayList<>();
try { try {
// 构建搜索请求 SearchRequest searchRequest = new SearchRequest(NoteConstant.RECORD_INDEX);
SearchRequest.Builder builder = new SearchRequest.Builder().index(NoteConstant.RECORD_INDEX); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 添加查询条件根据uid过滤 // 添加查询条件根据uid过滤
if (StringUtils.isNotBlank(uid)) { if (StringUtils.isNotBlank(uid)) {
builder.query(q -> q.bool(b -> { BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
b.must(m -> m.term(t -> t.field("uid").value(uid))); boolQuery.must(QueryBuilders.termQuery("uid", uid));
if (StringUtils.isNotBlank(keyword)) { if (StringUtils.isNotBlank(keyword)) {
b.must(m -> m.match(f -> f.field("content").query(keyword))); boolQuery.must(QueryBuilders.matchQuery("content", keyword));
} }
return b; sourceBuilder.query(boolQuery);
}));
} }
// 设置排序规则和高亮显示 // 设置排序规则和高亮显示
builder.sort(o -> o.field(f -> f.field("time").order(SortOrder.Desc))); sourceBuilder.sort("time", SortOrder.DESC);
builder.highlight(h -> h.fields("content", m -> m).preTags("<font color='black'>").postTags("</font>")); HighlightBuilder highlightBuilder = new HighlightBuilder();
builder.size(10); highlightBuilder.field("content");
highlightBuilder.preTags("<font color='black'>");
highlightBuilder.postTags("</font>");
sourceBuilder.highlighter(highlightBuilder);
sourceBuilder.size(10);
searchRequest.source(sourceBuilder);
// 执行搜索请求 // 执行搜索请求
SearchRequest searchRequest = builder.build(); SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchResponse<RecordSearchVO> searchResponse = elasticsearchClient.search(searchRequest, RecordSearchVO.class);
// 获取搜索结果 // 获取搜索结果
List<Hit<RecordSearchVO>> hits = searchResponse.hits().hits(); SearchHit[] hits = searchResponse.getHits().getHits();
// 处理搜索结果 // 处理搜索结果
for (Hit<RecordSearchVO> hit : hits) { for (SearchHit hit : hits) {
RecordSearchVO recordSearchVo = hit.source(); RecordSearchVO recordSearchVo = JSON.parseObject(hit.getSourceAsString(), RecordSearchVO.class);
records.add(recordSearchVo); records.add(recordSearchVo);
} }
@ -87,20 +105,22 @@ public class WebEsRecordServiceImpl implements IWebEsRecordService {
public List<RecordSearchVO> getHotRecord() { public List<RecordSearchVO> getHotRecord() {
List<RecordSearchVO> records = new ArrayList<>(); List<RecordSearchVO> records = new ArrayList<>();
try { try {
BooleanResponse exists = elasticsearchClient.indices().exists(e -> e GetIndexRequest getIndexRequest = new GetIndexRequest(NoteConstant.RECORD_INDEX);
.index(NoteConstant.RECORD_INDEX)); boolean exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
if (!exists.value()) { if (!exists) {
return records; return records;
} }
SearchRequest.Builder builder = new SearchRequest.Builder().index(NoteConstant.RECORD_INDEX);
builder.sort(o -> o.field(f -> f.field("searchCount").order(SortOrder.Desc))); SearchRequest searchRequest = new SearchRequest(NoteConstant.RECORD_INDEX);
builder.size(10); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
SearchRequest searchRequest = builder.build(); sourceBuilder.sort("searchCount", SortOrder.DESC);
SearchResponse<RecordSearchVO> searchResponse = elasticsearchClient.search(searchRequest, RecordSearchVO.class); sourceBuilder.size(10);
//得到所有的数据 searchRequest.source(sourceBuilder);
List<Hit<RecordSearchVO>> hits = searchResponse.hits().hits();
for (Hit<RecordSearchVO> hit : hits) { SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
RecordSearchVO recordSearchVo = hit.source(); SearchHit[] hits = searchResponse.getHits().getHits();
for (SearchHit hit : hits) {
RecordSearchVO recordSearchVo = JSON.parseObject(hit.getSourceAsString(), RecordSearchVO.class);
records.add(recordSearchVo); records.add(recordSearchVo);
} }
return records; return records;
@ -119,36 +139,47 @@ public class WebEsRecordServiceImpl implements IWebEsRecordService {
String uid = esRecordDTO.getUid(); String uid = esRecordDTO.getUid();
try { try {
// 查询索引是否存在 // 查询索引是否存在
BooleanResponse exists = elasticsearchClient.indices().exists(e -> e GetIndexRequest getIndexRequest = new GetIndexRequest(NoteConstant.RECORD_INDEX);
.index(NoteConstant.RECORD_INDEX)); boolean exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
if (!exists.value()) { if (!exists) {
elasticsearchClient.indices().create(c -> c.index(NoteConstant.RECORD_INDEX)); CreateIndexRequest createIndexRequest = new CreateIndexRequest(NoteConstant.RECORD_INDEX);
restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
} }
SearchRequest.Builder builder = new SearchRequest.Builder().index(NoteConstant.RECORD_INDEX);
SearchRequest searchRequest = new SearchRequest(NoteConstant.RECORD_INDEX);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
if (StringUtils.isNotBlank(keyword)) { if (StringUtils.isNotBlank(keyword)) {
builder.query(q -> q.match(f -> f.field("content").query(keyword.trim()))); sourceBuilder.query(QueryBuilders.matchQuery("content", keyword.trim()));
} }
builder.size(10); sourceBuilder.size(10);
SearchRequest searchRequest = builder.build(); searchRequest.source(sourceBuilder);
SearchResponse<RecordSearchVO> searchResponse = elasticsearchClient.search(searchRequest, RecordSearchVO.class);
//得到所有的数据 SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
List<Hit<RecordSearchVO>> hits = searchResponse.hits().hits(); SearchHit[] hits = searchResponse.getHits().getHits();
List<String> contents = new ArrayList<>(); List<String> contents = new ArrayList<>();
// 高亮查询 for (SearchHit hit : hits) {
for (Hit<RecordSearchVO> hit : hits) { RecordSearchVO recordSearchVo = JSON.parseObject(hit.getSourceAsString(), RecordSearchVO.class);
RecordSearchVO recordSearchVo = hit.source();
recordSearchVo.setSearchCount(recordSearchVo.getSearchCount() + 1); recordSearchVo.setSearchCount(recordSearchVo.getSearchCount() + 1);
UpdateResponse<RecordSearchVO> response = elasticsearchClient.update(u -> u.index(NoteConstant.RECORD_INDEX).id(hit.id()).doc(recordSearchVo), RecordSearchVO.class);
log.info("response", response.toString()); UpdateRequest updateRequest = new UpdateRequest(NoteConstant.RECORD_INDEX, hit.getId())
.doc(JSON.toJSONString(recordSearchVo), XContentType.JSON);
UpdateResponse response = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
log.info("response {}", response.toString());
contents.add(recordSearchVo.getContent()); contents.add(recordSearchVo.getContent());
} }
if (StringUtils.isNotBlank(keyword) && !contents.contains(keyword.trim())) { if (StringUtils.isNotBlank(keyword) && !contents.contains(keyword.trim())) {
RecordSearchVO recordSearchVo = new RecordSearchVO(); RecordSearchVO recordSearchVo = new RecordSearchVO();
recordSearchVo.setContent(keyword); recordSearchVo.setContent(keyword);
recordSearchVo.setSearchCount(1L); recordSearchVo.setSearchCount(1L);
recordSearchVo.setUid(uid);
String id = RandomUtil.randomString(12); String id = RandomUtil.randomString(12);
elasticsearchClient.create(c -> c.index(NoteConstant.RECORD_INDEX).id(id).document(recordSearchVo));
IndexRequest indexRequest = new IndexRequest(NoteConstant.RECORD_INDEX)
.id(id)
.source(JSON.toJSONString(recordSearchVo), XContentType.JSON);
restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -165,35 +196,31 @@ public class WebEsRecordServiceImpl implements IWebEsRecordService {
try { try {
// 检查索引是否存在 // 检查索引是否存在
BooleanResponse exists = elasticsearchClient.indices().exists(e -> e GetIndexRequest getIndexRequest = new GetIndexRequest(NoteConstant.RECORD_INDEX);
.index(NoteConstant.RECORD_INDEX)); boolean exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
if (!exists.value()) { if (!exists) {
log.warn("Index does not exist. No records to clear."); log.warn("Index does not exist. No records to clear.");
return; return;
} }
// 构建删除请求 // 构建删除请求
DeleteByQueryRequest.Builder deleteRequestBuilder = new DeleteByQueryRequest.Builder() DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(NoteConstant.RECORD_INDEX);
.index(NoteConstant.RECORD_INDEX) BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
.query(q -> q.bool(b -> { boolQuery.must(QueryBuilders.termQuery("uid", uid));
b.must(m -> m.term(t -> t.field("uid").value(uid))); if (StringUtils.isNotBlank(keyword)) {
if (StringUtils.isNotBlank(keyword)) { boolQuery.must(QueryBuilders.termQuery("content.keyword", keyword.trim()));
b.must(m -> m.term(t -> t.field("content.keyword").value(keyword.trim()))); }
} deleteByQueryRequest.setQuery(boolQuery);
return b;
}));
// 执行删除操作 // 执行删除操作
DeleteByQueryResponse deleteResponse = elasticsearchClient.deleteByQuery(deleteRequestBuilder.build()); BulkByScrollResponse deleteResponse = restHighLevelClient.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT);
log.info("Deleted {} records for uid: {}", deleteResponse.getDeleted(), uid);
log.info("Deleted {} records for uid: {}", deleteResponse.deleted(), uid);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
/** /**
* *
*/ */
@ -201,13 +228,15 @@ public class WebEsRecordServiceImpl implements IWebEsRecordService {
public void clearAllRecord() { public void clearAllRecord() {
try { try {
// 检查索引是否存在 // 检查索引是否存在
BooleanResponse exists = elasticsearchClient.indices().exists(e -> e GetIndexRequest getIndexRequest = new GetIndexRequest(NoteConstant.RECORD_INDEX);
.index(NoteConstant.RECORD_INDEX)); boolean exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
if (exists.value()) { if (exists) {
// 删除整个索引 // 删除整个索引
elasticsearchClient.indices().delete(d -> d.index(NoteConstant.RECORD_INDEX)); DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(NoteConstant.RECORD_INDEX);
restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
// 重新创建索引 // 重新创建索引
elasticsearchClient.indices().create(c -> c.index(NoteConstant.RECORD_INDEX)); CreateIndexRequest createIndexRequest = new CreateIndexRequest(NoteConstant.RECORD_INDEX);
restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
log.info("All search records have been cleared."); log.info("All search records have been cleared.");
} else { } else {
log.warn("Index does not exist. No records to clear."); log.warn("Index does not exist. No records to clear.");
@ -216,4 +245,4 @@ public class WebEsRecordServiceImpl implements IWebEsRecordService {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }

@ -41,7 +41,7 @@
<jwt.version>0.9.1</jwt.version> <jwt.version>0.9.1</jwt.version>
<lombok.version>1.18.24</lombok.version> <lombok.version>1.18.24</lombok.version>
<hutool.version>5.7.22</hutool.version> <hutool.version>5.7.22</hutool.version>
<elasticsearch.version>8.13.4</elasticsearch.version> <elasticsearch.version>7.12.1</elasticsearch.version>
<guava.version>20.0</guava.version> <guava.version>20.0</guava.version>
<gson.version>2.9.0</gson.version> <gson.version>2.9.0</gson.version>
<mybatisplus.version>3.5.2</mybatisplus.version> <mybatisplus.version>3.5.2</mybatisplus.version>
@ -153,26 +153,11 @@
<version>${hutool.version}</version> <version>${hutool.version}</version>
</dependency> </dependency>
<!-- elasticsearch--> <!-- elasticsearch-->
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.elasticsearch.client</groupId> <groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId> <artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>${elasticsearch.version}</version> <version>${elasticsearch.version}</version>
</dependency> </dependency>
<dependency>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.parsson</groupId>
<artifactId>parsson</artifactId>
<version>1.0.5</version>
</dependency>
<!-- guava--> <!-- guava-->
<dependency> <dependency>

Loading…
Cancel
Save