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>
</dependency>
<!-- es-->
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
</dependency>
<dependency>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.parsson</groupId>
<artifactId>parsson</artifactId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>
<!-- gson-->
<dependency>

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

@ -59,35 +59,3 @@ spring:
wall:
config:
multi-statement-allow: true
# redis 配置
redis:
# 地址
host: localhost
# 端口默认为6379
port: 6379
# 数据库索引
database: 0
# 密码
password:
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# ElasticSearch配置
es:
url: 192.168.3.90
port: 9200
username:
password:

@ -1,94 +0,0 @@
# 数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
# 主库数据源
master:
url: jdbc:mysql://192.168.3.90:3306/ipdz_ddns?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8
username: xuao
password: xuao@dev123!
# 从库数据源
slave:
# 从数据源开关/默认关闭
enabled: false
url:
username:
password:
# 初始连接数
initialSize: 5
# 最小连接池数量
minIdle: 10
# 最大连接池数量
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置连接超时时间
connectTimeout: 30000
# 配置网络超时时间
socketTimeout: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000
# 配置检测连接是否有效
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
webStatFilter:
enabled: true
statViewServlet:
enabled: true
# 设置白名单,不填则允许所有访问
allow:
url-pattern: /druid/*
# 控制台管理用户名和密码
login-username: admin
login-password: 123456
filter:
stat:
enabled: true
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true
# redis 配置
redis:
# 地址
host: redis.rpk.ipdz.me
# 端口默认为6379
port: 19379
# 数据库索引
database: 0
# 密码
password: guoguo
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# ElasticSearch配置
es:
url: 192.168.3.90
port: 9200
username: elastic
password: 8QJJIlWkxRe7Nn-Foj03

@ -52,7 +52,7 @@ spring:
# 国际化资源文件路径
basename: i18n/messages
profiles:
active: test
active: druid
# 文件上传
servlet:
multipart:
@ -66,6 +66,28 @@ spring:
# 热部署开关
enabled: true
# redis 配置
redis:
# 地址
host: localhost
# 端口默认为6379
port: 6379
# 数据库索引
database: 0
# 密码
password:
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# token配置
token:
@ -118,6 +140,12 @@ xss:
# 匹配链接
urlPatterns: /system/*,/monitor/*,/tool/*
# ElasticSearch配置
es:
url: localhost
port: 9200
username:
password:
# Oss配置
oss:

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

@ -1,14 +1,7 @@
package com.hongshu.web.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
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.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -32,6 +25,26 @@ import com.hongshu.web.service.IWebEsNoteService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
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.stereotype.Service;
@ -54,7 +67,7 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
@Autowired
private WebNoteMapper noteMapper;
@Autowired
private ElasticsearchClient elasticsearchClient;
private RestHighLevelClient restHighLevelClient;
@Autowired
private WebLikeOrCollectMapper likeOrCollectionMapper;
@ -71,40 +84,48 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
Page<NoteSearchVO> page = new Page<>();
List<NoteSearchVO> noteSearchVOList = new ArrayList<>();
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())) {
builder.query(q -> q.bool(b -> b
.should(h -> h.match(f -> f.field("title").boost(1f).query(esNoteDTO.getKeyword())))
.should(h -> h.match(f -> f.field("username").boost(0.5f).query(esNoteDTO.getKeyword())))
.should(h -> h.match(f -> f.field("content").boost(1f).query(esNoteDTO.getKeyword())))
.should(h -> h.match(f -> f.field("tags").boost(4f).query(esNoteDTO.getKeyword())))
.should(h -> h.match(f -> f.field("categoryName").boost(2f).query(esNoteDTO.getKeyword())))
.should(h -> h.match(f -> f.field("categoryParentName").boost(1.5f).query(esNoteDTO.getKeyword())))
));
BoolQueryBuilder keywordQuery = QueryBuilders.boolQuery()
.should(QueryBuilders.matchQuery("title", esNoteDTO.getKeyword()).boost(1f))
.should(QueryBuilders.matchQuery("username", esNoteDTO.getKeyword()).boost(0.5f))
.should(QueryBuilders.matchQuery("content", esNoteDTO.getKeyword()).boost(1f))
.should(QueryBuilders.matchQuery("tags", esNoteDTO.getKeyword()).boost(4f))
.should(QueryBuilders.matchQuery("categoryName", esNoteDTO.getKeyword()).boost(2f))
.should(QueryBuilders.matchQuery("categoryParentName", esNoteDTO.getKeyword()).boost(1.5f));
mainQuery.must(keywordQuery);
}
if (StringUtils.isNotBlank(esNoteDTO.getCpid()) && StringUtils.isNotBlank(esNoteDTO.getCid())) {
builder.query(q -> q.bool(b -> b
.must(h -> h.match(m -> m.field("cid").query(esNoteDTO.getCid())))
.must(h -> h.match(m -> m.field("cpid").query(esNoteDTO.getCpid())))
));
mainQuery.must(QueryBuilders.matchQuery("cid", esNoteDTO.getCid()))
.must(QueryBuilders.matchQuery("cpid", 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) {
builder.sort(o -> o.field(f -> f.field("likeCount").order(SortOrder.Desc)));
sourceBuilder.sort("likeCount", SortOrder.DESC);
} else if (esNoteDTO.getType() == 2) {
builder.sort(o -> o.field(f -> f.field("time").order(SortOrder.Desc)));
}
builder.from((int) (currentPage - 1) * (int) pageSize);
builder.size((int) pageSize);
SearchRequest searchRequest = builder.build();
SearchResponse<NoteSearchVO> searchResponse = elasticsearchClient.search(searchRequest, NoteSearchVO.class);
TotalHits totalHits = searchResponse.hits().total();
page.setTotal(Objects.requireNonNull(totalHits).value());
List<Hit<NoteSearchVO>> hits = searchResponse.hits().hits();
for (Hit<NoteSearchVO> hit : hits) {
NoteSearchVO noteSearchVo = hit.source();
sourceBuilder.sort("time", SortOrder.DESC);
}
sourceBuilder.from((int) (currentPage - 1) * (int) pageSize);
sourceBuilder.size((int) pageSize);
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
long totalHits = searchResponse.getHits().getTotalHits().value;
page.setTotal(totalHits);
for (SearchHit hit : searchResponse.getHits().getHits()) {
NoteSearchVO noteSearchVo = JSON.parseObject(hit.getSourceAsString(), NoteSearchVO.class);
noteSearchVOList.add(noteSearchVo);
}
} catch (Exception e) {
@ -139,23 +160,25 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
List<NoteSearchVO> noteSearchVOList = new ArrayList<>();
//得到当前用户的浏览记录
try {
SearchRequest.Builder builder = new SearchRequest.Builder().index(NoteConstant.NOTE_INDEX);
builder.size(1000);
SearchRequest searchRequest = builder.build();
SearchResponse<NoteSearchVO> searchResponse = elasticsearchClient.search(searchRequest, NoteSearchVO.class);
TotalHits totalHits = searchResponse.hits().total();
//得到所有的数据
List<Hit<NoteSearchVO>> hits = searchResponse.hits().hits();
if (CollectionUtil.isNotEmpty(hits)) {
for (Hit<NoteSearchVO> hit : hits) {
NoteSearchVO noteSearchVo = hit.source();
SearchRequest searchRequest = new SearchRequest(NoteConstant.NOTE_INDEX);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.size(1000);
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
long totalHits = searchResponse.getHits().getTotalHits().value;
SearchHit[] hits = searchResponse.getHits().getHits();
if (hits.length > 0) {
for (SearchHit hit : hits) {
NoteSearchVO noteSearchVo = JSON.parseObject(hit.getSourceAsString(), NoteSearchVO.class);
noteSearchVOList.add(noteSearchVo);
}
Collections.shuffle(noteSearchVOList);
List<List<NoteSearchVO>> partition = Lists.partition(noteSearchVOList, (int) pageSize);
List<NoteSearchVO> noteSearchVOS = partition.get((int) currentPage - 1);
page.setTotal(totalHits != null ? totalHits.value() : 0);
page.setTotal(totalHits);
page.setRecords(noteSearchVOS);
}
} catch (Exception e) {
@ -176,15 +199,19 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
Page<WebUser> page = new Page<>();
String userId = WebUtils.getRequestHeader(UserConstant.USER_ID);
// 用户ID为空 默认随机加载100条数据
List<WebUser> recommendList = null;
List<WebUser> recommendList = new ArrayList<>();
if (StringUtils.isBlank(userId)) {
SearchRequest searchRequest = SearchRequest.of(s -> s
.index(NoteConstant.NOTE_INDEX)
.size(100));
SearchResponse<WebUser> searchResponse = elasticsearchClient.search(searchRequest, WebUser.class);
recommendList = searchResponse.hits().hits().stream()
.map(Hit::source)
.collect(Collectors.toList());
SearchRequest searchRequest = new SearchRequest(NoteConstant.NOTE_INDEX);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.size(100);
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
for (SearchHit hit : searchResponse.getHits().getHits()) {
WebUser user = JSON.parseObject(hit.getSourceAsString(), WebUser.class);
recommendList.add(user);
}
// 随机排序
Collections.shuffle(recommendList, new Random());
} else {
@ -198,6 +225,7 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
page.setRecords(Collections.emptyList());
return page;
}
List<WebUser> userList = partition.get((int) currentPage - 1);
page.setTotal(recommendList.size());
page.setRecords(userList);
@ -216,35 +244,29 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
List<NoteSearchVO> noteSearchVOList = new ArrayList<>();
try {
// 构建搜索请求
SearchRequest.Builder builder = new SearchRequest.Builder()
.index(NoteConstant.NOTE_INDEX)
.from(Math.toIntExact((currentPage - 1) * pageSize)) // 设置分页起始点
.size(Math.toIntExact(pageSize)) // 设置分页大小
.sort(s -> s.field(f -> f.field("likeCount").order(SortOrder.Desc))); // 按 likeCount 降序排序
SearchRequest searchRequest = builder.build();
// 执行搜索请求
SearchResponse<NoteSearchVO> searchResponse = elasticsearchClient.search(searchRequest, NoteSearchVO.class);
TotalHits totalHits = searchResponse.hits().total();
// 获取搜索结果
List<Hit<NoteSearchVO>> hits = searchResponse.hits().hits();
if (CollectionUtil.isNotEmpty(hits)) {
for (Hit<NoteSearchVO> hit : hits) {
NoteSearchVO noteSearchVo = hit.source();
SearchRequest searchRequest = new SearchRequest(NoteConstant.NOTE_INDEX);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.from(Math.toIntExact((currentPage - 1) * pageSize));
sourceBuilder.size(Math.toIntExact(pageSize));
sourceBuilder.sort("likeCount", SortOrder.DESC);
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
long totalHits = searchResponse.getHits().getTotalHits().value;
SearchHit[] hits = searchResponse.getHits().getHits();
if (hits.length > 0) {
for (SearchHit hit : hits) {
NoteSearchVO noteSearchVo = JSON.parseObject(hit.getSourceAsString(), NoteSearchVO.class);
noteSearchVOList.add(noteSearchVo);
}
}
// 设置分页结果
page.setTotal(totalHits != null ? totalHits.value() : 0);
page.setTotal(totalHits);
page.setRecords(noteSearchVOList);
} catch (Exception e) {
e.printStackTrace();
// 这里可以进一步处理异常,比如记录日志或者抛出自定义异常
}
return page;
}
@ -257,8 +279,11 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
@Override
public void addNote(NoteSearchVO noteSearchVo) {
try {
CreateResponse createResponse = elasticsearchClient.create(e -> e.index(NoteConstant.NOTE_INDEX).id(noteSearchVo.getId()).document(noteSearchVo));
log.info("createResponse.result{}", createResponse.result());
IndexRequest indexRequest = new IndexRequest(NoteConstant.NOTE_INDEX)
.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) {
e.printStackTrace();
}
@ -272,8 +297,10 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
@Override
public void updateNote(NoteSearchVO noteSearchVo) {
try {
UpdateResponse<NoteSearchVO> updateResponse = elasticsearchClient.update(e -> e.index(NoteConstant.NOTE_INDEX).id(noteSearchVo.getId()).doc(noteSearchVo), NoteSearchVO.class);
log.info("updateResponse.result() = " + updateResponse.result());
UpdateRequest updateRequest = new UpdateRequest(NoteConstant.NOTE_INDEX, noteSearchVo.getId())
.doc(JSON.toJSONString(noteSearchVo), XContentType.JSON);
UpdateResponse updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
log.info("updateResponse.result() = " + updateResponse.getResult());
} catch (Exception e) {
e.printStackTrace();
}
@ -287,8 +314,9 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
@Override
public void deleteNote(String noteId) {
try {
DeleteResponse deleteResponse = elasticsearchClient.delete(e -> e.index(NoteConstant.NOTE_INDEX).id(String.valueOf(noteId)));
log.info("deleteResponse.result() ={} ", deleteResponse.result());
DeleteRequest deleteRequest = new DeleteRequest(NoteConstant.NOTE_INDEX, String.valueOf(noteId));
DeleteResponse deleteResponse = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
log.info("deleteResponse.result() ={} ", deleteResponse.getResult());
} catch (Exception e) {
e.printStackTrace();
}
@ -316,13 +344,15 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
noteSearchVo.setIsLike(likeOrCollectionIds.contains(noteSearchVo.getId()));
}
try {
List<BulkOperation> result = new ArrayList<>();
BulkRequest bulkRequest = new BulkRequest();
for (NoteSearchVO noteSearchVo : noteSearchVOList) {
result.add(new BulkOperation.Builder().create(
d -> d.document(noteSearchVo).id(noteSearchVo.getId()).index(NoteConstant.NOTE_INDEX)).build());
IndexRequest indexRequest = new IndexRequest(NoteConstant.NOTE_INDEX)
.id(noteSearchVo.getId())
.source(JSON.toJSONString(noteSearchVo), XContentType.JSON);
bulkRequest.add(indexRequest);
}
BulkResponse bulkResponse = elasticsearchClient.bulk(e -> e.index(NoteConstant.NOTE_INDEX).operations(result));
log.info("createResponse.result{}", bulkResponse.toString());
BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
log.info("createResponse.result{}", bulkResponse.hasFailures() ? "has failures" : "success");
} catch (Exception e) {
e.printStackTrace();
}
@ -335,16 +365,19 @@ public class WebEsNoteServiceImpl extends ServiceImpl<WebNoteMapper, WebNote> im
public void delNoteBulkData() {
try {
// 删除索引
DeleteIndexRequest deleteIndexRequest = DeleteIndexRequest.of(builder -> builder.index(NoteConstant.NOTE_INDEX));
elasticsearchClient.indices().delete(deleteIndexRequest);
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(NoteConstant.NOTE_INDEX);
restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
log.info("删除索引:{}", NoteConstant.NOTE_INDEX);
} catch (Exception e) {
log.error("删除索引异常 (可能不存在): {}", NoteConstant.NOTE_INDEX);
}
try {
// 重新创建索引
CreateIndexRequest createIndexRequest = CreateIndexRequest.of(builder -> builder.index(NoteConstant.NOTE_INDEX));
elasticsearchClient.indices().create(createIndexRequest);
CreateIndexRequest createIndexRequest = new CreateIndexRequest(NoteConstant.NOTE_INDEX);
restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
log.info("创建索引:{}", NoteConstant.NOTE_INDEX);
} 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;
import cn.hutool.core.util.RandomUtil;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
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.alibaba.fastjson2.JSON;
import com.hongshu.common.constant.NoteConstant;
import com.hongshu.web.domain.dto.EsRecordDTO;
import com.hongshu.web.domain.vo.RecordSearchVO;
import com.hongshu.web.service.IWebEsRecordService;
import lombok.extern.slf4j.Slf4j;
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.stereotype.Service;
@ -28,8 +43,7 @@ import java.util.List;
public class WebEsRecordServiceImpl implements IWebEsRecordService {
@Autowired
ElasticsearchClient elasticsearchClient;
private RestHighLevelClient restHighLevelClient;
/**
*
@ -41,35 +55,39 @@ public class WebEsRecordServiceImpl implements IWebEsRecordService {
List<RecordSearchVO> records = new ArrayList<>();
try {
// 构建搜索请求
SearchRequest.Builder builder = new SearchRequest.Builder().index(NoteConstant.RECORD_INDEX);
SearchRequest searchRequest = new SearchRequest(NoteConstant.RECORD_INDEX);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 添加查询条件根据uid过滤
if (StringUtils.isNotBlank(uid)) {
builder.query(q -> q.bool(b -> {
b.must(m -> m.term(t -> t.field("uid").value(uid)));
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.must(QueryBuilders.termQuery("uid", uid));
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)));
builder.highlight(h -> h.fields("content", m -> m).preTags("<font color='black'>").postTags("</font>"));
builder.size(10);
sourceBuilder.sort("time", SortOrder.DESC);
HighlightBuilder highlightBuilder = new HighlightBuilder();
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<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();
// 处理搜索结果
for (Hit<RecordSearchVO> hit : hits) {
RecordSearchVO recordSearchVo = hit.source();
for (SearchHit hit : hits) {
RecordSearchVO recordSearchVo = JSON.parseObject(hit.getSourceAsString(), RecordSearchVO.class);
records.add(recordSearchVo);
}
@ -87,20 +105,22 @@ public class WebEsRecordServiceImpl implements IWebEsRecordService {
public List<RecordSearchVO> getHotRecord() {
List<RecordSearchVO> records = new ArrayList<>();
try {
BooleanResponse exists = elasticsearchClient.indices().exists(e -> e
.index(NoteConstant.RECORD_INDEX));
if (!exists.value()) {
GetIndexRequest getIndexRequest = new GetIndexRequest(NoteConstant.RECORD_INDEX);
boolean exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
if (!exists) {
return records;
}
SearchRequest.Builder builder = new SearchRequest.Builder().index(NoteConstant.RECORD_INDEX);
builder.sort(o -> o.field(f -> f.field("searchCount").order(SortOrder.Desc)));
builder.size(10);
SearchRequest searchRequest = builder.build();
SearchResponse<RecordSearchVO> searchResponse = elasticsearchClient.search(searchRequest, RecordSearchVO.class);
//得到所有的数据
List<Hit<RecordSearchVO>> hits = searchResponse.hits().hits();
for (Hit<RecordSearchVO> hit : hits) {
RecordSearchVO recordSearchVo = hit.source();
SearchRequest searchRequest = new SearchRequest(NoteConstant.RECORD_INDEX);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.sort("searchCount", SortOrder.DESC);
sourceBuilder.size(10);
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hits = searchResponse.getHits().getHits();
for (SearchHit hit : hits) {
RecordSearchVO recordSearchVo = JSON.parseObject(hit.getSourceAsString(), RecordSearchVO.class);
records.add(recordSearchVo);
}
return records;
@ -119,36 +139,47 @@ public class WebEsRecordServiceImpl implements IWebEsRecordService {
String uid = esRecordDTO.getUid();
try {
// 查询索引是否存在
BooleanResponse exists = elasticsearchClient.indices().exists(e -> e
.index(NoteConstant.RECORD_INDEX));
if (!exists.value()) {
elasticsearchClient.indices().create(c -> c.index(NoteConstant.RECORD_INDEX));
GetIndexRequest getIndexRequest = new GetIndexRequest(NoteConstant.RECORD_INDEX);
boolean exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
if (!exists) {
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)) {
builder.query(q -> q.match(f -> f.field("content").query(keyword.trim())));
sourceBuilder.query(QueryBuilders.matchQuery("content", keyword.trim()));
}
builder.size(10);
SearchRequest searchRequest = builder.build();
SearchResponse<RecordSearchVO> searchResponse = elasticsearchClient.search(searchRequest, RecordSearchVO.class);
//得到所有的数据
List<Hit<RecordSearchVO>> hits = searchResponse.hits().hits();
sourceBuilder.size(10);
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hits = searchResponse.getHits().getHits();
List<String> contents = new ArrayList<>();
// 高亮查询
for (Hit<RecordSearchVO> hit : hits) {
RecordSearchVO recordSearchVo = hit.source();
for (SearchHit hit : hits) {
RecordSearchVO recordSearchVo = JSON.parseObject(hit.getSourceAsString(), RecordSearchVO.class);
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());
}
if (StringUtils.isNotBlank(keyword) && !contents.contains(keyword.trim())) {
RecordSearchVO recordSearchVo = new RecordSearchVO();
recordSearchVo.setContent(keyword);
recordSearchVo.setSearchCount(1L);
recordSearchVo.setUid(uid);
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) {
e.printStackTrace();
@ -165,35 +196,31 @@ public class WebEsRecordServiceImpl implements IWebEsRecordService {
try {
// 检查索引是否存在
BooleanResponse exists = elasticsearchClient.indices().exists(e -> e
.index(NoteConstant.RECORD_INDEX));
if (!exists.value()) {
GetIndexRequest getIndexRequest = new GetIndexRequest(NoteConstant.RECORD_INDEX);
boolean exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
if (!exists) {
log.warn("Index does not exist. No records to clear.");
return;
}
// 构建删除请求
DeleteByQueryRequest.Builder deleteRequestBuilder = new DeleteByQueryRequest.Builder()
.index(NoteConstant.RECORD_INDEX)
.query(q -> q.bool(b -> {
b.must(m -> m.term(t -> t.field("uid").value(uid)));
DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(NoteConstant.RECORD_INDEX);
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.must(QueryBuilders.termQuery("uid", uid));
if (StringUtils.isNotBlank(keyword)) {
b.must(m -> m.term(t -> t.field("content.keyword").value(keyword.trim())));
boolQuery.must(QueryBuilders.termQuery("content.keyword", keyword.trim()));
}
return b;
}));
deleteByQueryRequest.setQuery(boolQuery);
// 执行删除操作
DeleteByQueryResponse deleteResponse = elasticsearchClient.deleteByQuery(deleteRequestBuilder.build());
log.info("Deleted {} records for uid: {}", deleteResponse.deleted(), uid);
BulkByScrollResponse deleteResponse = restHighLevelClient.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT);
log.info("Deleted {} records for uid: {}", deleteResponse.getDeleted(), uid);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
*
*/
@ -201,13 +228,15 @@ public class WebEsRecordServiceImpl implements IWebEsRecordService {
public void clearAllRecord() {
try {
// 检查索引是否存在
BooleanResponse exists = elasticsearchClient.indices().exists(e -> e
.index(NoteConstant.RECORD_INDEX));
if (exists.value()) {
GetIndexRequest getIndexRequest = new GetIndexRequest(NoteConstant.RECORD_INDEX);
boolean exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
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.");
} else {
log.warn("Index does not exist. No records to clear.");

@ -25,7 +25,7 @@
<hongshu.version>1.0.0</hongshu.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>17</java.version>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<spring-framework.version>5.3.33</spring-framework.version>
<druid.version>1.2.20</druid.version>
@ -41,7 +41,7 @@
<jwt.version>0.9.1</jwt.version>
<lombok.version>1.18.24</lombok.version>
<hutool.version>5.7.22</hutool.version>
<elasticsearch.version>9.0.1</elasticsearch.version>
<elasticsearch.version>7.12.1</elasticsearch.version>
<guava.version>20.0</guava.version>
<gson.version>2.9.0</gson.version>
<mybatisplus.version>3.5.2</mybatisplus.version>
@ -153,26 +153,11 @@
<version>${hutool.version}</version>
</dependency>
<!-- elasticsearch-->
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>${elasticsearch.version}</version>
</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-->
<dependency>

Loading…
Cancel
Save