
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com..core.elasticsearch.utils.bean.ScrollPageBean;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
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.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
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.search.SearchScrollRequest;
import org.elasticsearch.action.support.WriteRequest;
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.text.Text;
import org.elasticsearch.common.unit.Timevalue;
import org.elasticsearch.common.xcontent.XContentType;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@Slf4j
@ConditionalOnClass({RestHighLevelClient.class})
@Component
public class ElasticsearchUtil {
@Autowired
private RestHighLevelClient esClient;
@SneakyThrows
public void saveWithId(String index, Object data, String id, String dateFormat, boolean immediate) {
if (dateFormat == null) {
dateFormat = DatePattern.NORM_DATETIME_PATTERN;
}
IndexRequest request = new IndexRequest(index, index, id);
if (immediate) {
request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
}
request.source(new JSonObject(data, new JSonConfig().setDateFormat(dateFormat)).toString()
, XContentType.JSON);
IndexResponse response = esClient.index(request, RequestOptions.DEFAULT);
if (log.isInfoEnabled()) {
log.info("ES-带id添加,index: {}, type: {}, id: {}, result: {}", index, index, id, response.getResult());
}
}
@SneakyThrows
public void updateById(String index, Object data, String id, String dateFormat, boolean immediate) {
if (dateFormat == null) {
dateFormat = DatePattern.NORM_DATETIME_PATTERN;
}
UpdateRequest request = new UpdateRequest(index, index, id);
if (immediate) {
request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
}
request.doc(new JSonObject(data, new JSonConfig().setDateFormat(dateFormat)).toString()
, XContentType.JSON);
UpdateResponse response = esClient.update(request, RequestOptions.DEFAULT);
if (log.isInfoEnabled()) {
log.info("ES-根据id更新,index: {}, type: {}, id: {}, result: {}", index, index, id, response.getResult());
}
}
@SneakyThrows
public void batchSaveWithId(String index, Map dataMap, boolean immediate) {
BulkRequest bulkRequest = new BulkRequest();
dataMap.forEach((id, data) -> bulkRequest.add(new IndexRequest(index, index, id).source(JSON.toJSonString(data), XContentType.JSON)));
if (immediate) {
bulkRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
}
esClient.bulk(bulkRequest, RequestOptions.DEFAULT);
if (log.isInfoEnabled()) {
log.info("ES-带id批量添加,index: {}, type: {}, ids:{}", index, index, dataMap.keySet());
}
}
@SneakyThrows
public void deleteById(String index, String id, boolean immediate) {
DeleteRequest request = new DeleteRequest(index, index, id);
if (immediate) {
request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
}
DeleteResponse response = esClient.delete(request, RequestOptions.DEFAULT);
if (log.isInfoEnabled()) {
log.info("ES-根据id删除,index: {}, type: {}, id: {}, result: {}", index, index, id, response.getResult());
}
}
@SneakyThrows
public T getById(String index, String id, Class clazz) {
T result = null;
GetRequest request = new GetRequest(index, index, id);
GetResponse response = esClient.get(request, RequestOptions.DEFAULT);
if (response.isExists()) {
result = JSON.parseObject(response.getSourceAsString(), clazz);
}
if (log.isInfoEnabled()) {
log.info("ES-根据id查询,index: {}, type: {}, id: {}, isExists: {}", index, index, id, response.isExists());
}
return result;
}
public IPage page(String index, SearchSourceBuilder searchSourceBuilder, Class resultClass, int currentPage, int size, List highFields) {
SearchRequest request = new SearchRequest(index);
// 高亮字段设置
if (CollectionUtil.isNotEmpty(highFields)) {
buildHighLight(searchSourceBuilder, highFields);
}
request.source(searchSourceBuilder);
SearchResponse response = null;
try {
response = esClient.search(request, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
return analysisResponse(response, resultClass, currentPage, size, highFields);
}
private IPage analysisResponse(SearchResponse response, Class resultClass, int currentPage, int size, List highFields) {
SearchHit[] searchHits = response.getHits().getHits();
List retList = new ArrayList<>(searchHits.length);
for (SearchHit searchHit : searchHits) {
String strJson = searchHit.getSourceAsString();
T t = JSON.parseObject(strJson, resultClass);
try {
setId(resultClass, t, searchHit.getId());
} catch (Exception e) {
log.info("es 查询数据设置主键id值异常", e);
}
if (CollectionUtil.isNotEmpty(highFields)) {
Map highlightFieldMap = searchHit.getHighlightFields();
HighlightField highlightField;
for (String field : highFields) {
highlightField = highlightFieldMap.get(field);
if (highlightField != null) {
// 获取指定字段的高亮片段
Text[] fragments = highlightField.getFragments();
// 将这些高亮片段拼接成一个完整的高亮字段
StringBuilder builder = new StringBuilder();
for (Text text : fragments) {
builder.append(text);
}
// 设置到实体类中
setValue(resultClass, t, builder.toString(), field);
}
}
}
retList.add(t);
}
long totalNum = response.getHits().getTotalHits();
IPage pageVo = new Page<>(currentPage, size, totalNum);
pageVo.setRecords(retList);
return pageVo;
}
public BulkResponse batchDelete(String index, Collection idList, boolean immediate) {
BulkRequest request = new BulkRequest();
for (T t : idList) {
request.add(new DeleteRequest(index, index, t.toString()));
}
if (immediate) {
request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
}
BulkResponse response = null;
try {
response = esClient.bulk(request, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
@SneakyThrows
private void setId(Class resultClass, T t, String id) {
Field field = ReflectionUtils.findField(resultClass, "id");
if (null != field) {
field.setAccessible(true);
Object object = ReflectionUtils.getField(field, t);
if (object == null) {
Method method = null ;
Object value = null;
try {
if (NumberUtil.isLong(id)) {
method = resultClass.getMethod("setId", Long.class);
value = Long.valueOf(id);
} else {
method = resultClass.getMethod("setId", String.class);
value = id;
}
}catch (NoSuchMethodException e){
throw new NoSuchMethodException("id 未找到对应的setId()方法,赋值失败");
}
ReflectionUtils.invokeMethod(method, t,value);
}
}
}
@SneakyThrows
private void setValue(Class resultClass, T t, Object fieldValue, String fieldName) {
Field field = ReflectionUtils.findField(resultClass, fieldName);
if (null != field) {
field.setAccessible(true);
String methodName = "set".concat(captureName(fieldName));
Method method = null;
try {
method = resultClass.getMethod(methodName, String.class);
} catch (NoSuchMethodException e) {
throw new NoSuchMethodException(fieldName+"非普通的set方法,赋值失败");
}
ReflectionUtils.invokeMethod(method, t, fieldValue);
}
}
private String captureName(String str) {
char[] cs = str.toCharArray();
cs[0] -= 32;
return String.valueOf(cs);
}
public ScrollPageBean scrollPage(String indexName, SearchSourceBuilder searchSourceBuilder, String scrollId,
Class resultClass, int size, int minutes, List highFields) throws IOException {
SearchResponse searchResponse = null;
if (minutes == 0) {
minutes = 3;
}
if (scrollId == null) {
SearchRequest searchRequest = new SearchRequest(indexName);
// 高亮字段设置
if (CollectionUtil.isNotEmpty(highFields)) {
buildHighLight(searchSourceBuilder, highFields);
}
// 调用SearchRequest.source将查询条件设置到检索请求
searchRequest.source(searchSourceBuilder);
// 设置scroll查询
searchRequest.scroll(Timevalue.timevalueMinutes(minutes));
searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);
} else {
// 第二次查询的时候,直接通过scroll id查询数据
SearchScrollRequest searchScrollRequest = new SearchScrollRequest(scrollId);
searchScrollRequest.scroll(Timevalue.timevalueMinutes(minutes));
// 使用RestHighLevelClient发送scroll请求
searchResponse = esClient.scroll(searchScrollRequest, RequestOptions.DEFAULT);
}
IPage scrollPage = analysisResponse(searchResponse, resultClass, 0, size, highFields);
return new ScrollPageBean(searchResponse.getScrollId(), scrollPage);
}
private void buildHighLight(SearchSourceBuilder searchSourceBuilder, List fields) {
// 设置高亮
HighlightBuilder highlightBuilder = new HighlightBuilder();
fields.forEach(field -> {
highlightBuilder.field(field);
});
highlightBuilder.preTags("");
highlightBuilder.postTags("");
// 给请求设置高亮
searchSourceBuilder.highlighter(highlightBuilder);
}
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)