From 93b03e14f7319d6a003169b4cb471edf05cdbcb4 Mon Sep 17 00:00:00 2001 From: fanghongchao <601470458@qq.com> Date: Tue, 27 Nov 2018 17:59:24 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0elasticsearch=20=E5=B7=A5?= =?UTF-8?q?=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 42 ++ .../settings/UISettingsController.java | 44 +- .../domain/elasticsearch/UserOptLog.java | 154 +++++++ .../primary/dao/settings/UisettingsDao.java | 4 + .../primary/entity/settings/Uisettings.java | 1 + .../com/gzzn/omms/adminapi/dto/EsPage.java | 84 ++++ .../omms/adminapi/service/IUserService.java | 8 + .../service/impl/UserServiceImpl.java | 38 ++ .../adminapi/utils/ElasticsearchUtil.java | 400 ++++++++++++++++++ src/main/resources/application-dev.yml | 12 +- 10 files changed, 784 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/gzzn/omms/adminapi/domain/elasticsearch/UserOptLog.java create mode 100644 src/main/java/com/gzzn/omms/adminapi/dto/EsPage.java create mode 100644 src/main/java/com/gzzn/omms/adminapi/utils/ElasticsearchUtil.java diff --git a/pom.xml b/pom.xml index 97c127d..f46decb 100644 --- a/pom.xml +++ b/pom.xml @@ -104,6 +104,48 @@ spring-boot-devtools true + + + + + + org.elasticsearch + elasticsearch + 6.4.2 + + + + + org.elasticsearch.client + transport + 6.4.2 + + + org.elasticsearch + elasticsearch + + + + + + org.projectlombok + lombok + 1.16.20 + + + + com.alibaba + fastjson + 1.2.15 + diff --git a/src/main/java/com/gzzn/omms/adminapi/controller/settings/UISettingsController.java b/src/main/java/com/gzzn/omms/adminapi/controller/settings/UISettingsController.java index 87022ea..12205ce 100644 --- a/src/main/java/com/gzzn/omms/adminapi/controller/settings/UISettingsController.java +++ b/src/main/java/com/gzzn/omms/adminapi/controller/settings/UISettingsController.java @@ -8,6 +8,8 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.GetMapping; @@ -16,6 +18,8 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import com.alibaba.fastjson.JSONObject; +import com.gzzn.omms.adminapi.domain.elasticsearch.UserOptLog; import com.gzzn.omms.adminapi.domain.primary.dao.settings.UisettingsDao; import com.gzzn.omms.adminapi.domain.primary.entity.settings.Uisettings; import com.gzzn.omms.adminapi.dto.ResponseDto; @@ -23,10 +27,22 @@ import com.gzzn.omms.adminapi.dto.settings.UisettingsDto; import com.gzzn.omms.adminapi.dto.settings.convert.UisettingsConvert; import com.gzzn.omms.adminapi.service.IUserService; import com.gzzn.omms.adminapi.utils.CommonUtils; +import com.gzzn.omms.adminapi.utils.ElasticsearchUtil; +import com.gzzn.omms.adminapi.utils.JsonUtil; @RestController public class UISettingsController { + private final Logger logger = LoggerFactory.getLogger(UISettingsController.class); + /** + * 测试索引 + */ + private final String INDEX_NAME = "oplog"; + /** + * 类型 + */ + private String ES_TYPE = "oplog"; + /** * UI设置接口 */ @@ -41,7 +57,8 @@ public class UISettingsController { * 获取当前用户ID */ @Autowired - private IUserService iUserService; + private IUserService userService; + /** * 根据条件查找当前用户所有UI设置 * @return @@ -75,7 +92,6 @@ public class UISettingsController { UisettingsDto dto = uisettingsConvert.uisettingsToUisettingsDto(x); return dto; }).collect(Collectors.toList()); - return ResponseDto.success(uisettingsListDto); } @@ -92,13 +108,37 @@ public class UISettingsController { //Dto转实体类 Uisettings uisettings = uisettingsConvert.uisettingsDtoToUisettings(uisettingsDto); + Uisettings oldUisettings = null; if(StringUtils.isEmpty(uisettings.getId())) { uisettings.setId(CommonUtils.getUUID32()); //uuid自动生成 + }else{ + oldUisettings = uisettingsDao.findByUserid(uisettings.getId()); } uisettings = uisettingsDao.save(uisettings); + try { + if (!ElasticsearchUtil.isIndexExist(INDEX_NAME)) { + ElasticsearchUtil.createIndex(INDEX_NAME); + } + + UserOptLog oplog = new UserOptLog(null, "更新或者新增用户设置", userService.getCurrentUserId(),userService.getCurrentUserName(), + userService.getCurrentUserRealName(), userService.getUserRemoteAddress().getHostString(), + this.getClass().getMethod("saveUISettings", UisettingsDto.class).getAnnotation(ApiOperation.class).value()); + //设置日志类容 jsonarry 历史及最新的 + JSONObject log_content = new JSONObject(); + log_content.put("newData", JsonUtil.getString(uisettings)); + log_content.put("oldData", null==oldUisettings?"无":JsonUtil.getString(oldUisettings)); + oplog.setLog_content(log_content.toString()); + JSONObject logJson = JSONObject.parseObject(JsonUtil.getString(oplog)); + String id = ElasticsearchUtil.addData(logJson, INDEX_NAME, ES_TYPE); + logger.info("保存用户设置UI操作日志至Elatsticsearch成功:id="+id); + } catch (Exception e) { + logger.error("保存用户设置UI操作日志至Elatsticsearch异常:", e); + } + return ResponseDto.success(uisettings.getId()); } + } diff --git a/src/main/java/com/gzzn/omms/adminapi/domain/elasticsearch/UserOptLog.java b/src/main/java/com/gzzn/omms/adminapi/domain/elasticsearch/UserOptLog.java new file mode 100644 index 0000000..025c322 --- /dev/null +++ b/src/main/java/com/gzzn/omms/adminapi/domain/elasticsearch/UserOptLog.java @@ -0,0 +1,154 @@ +package com.gzzn.omms.adminapi.domain.elasticsearch; + +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Data +@ToString +@NoArgsConstructor +public class UserOptLog { + + private String id; + + /** + * 标题 + */ + private String title; + /** + * 应用名 + */ + private String app_name = "adminapi"; + /** + * 模块名 + */ + private String model_name; + /** + * 日志详情 + */ + private String log_content; + /** + * 操作日志类别 固定为oplog + */ + private String log_type = "oplog"; + /** + * 操作用户id + */ + private String user_id; + /** + * 操作用户登录名 + */ + private String user_name; + /** + * 操作用户真实姓名 + */ + private String real_name; + /** + * 用户登录IP + */ + private String login_ip; + /** + * 操作描述 + */ + private String summary; + + public UserOptLog() { + } + + /** + * + * @param title 标题 + * @param model_name 模块名 + * @param user_id 操作用户id + * @param user_name 操作用户登录名 + * @param real_name 操作用户真实姓名 + * @param login_ip 用户登录IP + * @param summary 操作描述 + */ + public UserOptLog(String title, String model_name, String user_id, + String user_name, String real_name, String login_ip, String summary) { + super(); + this.title = title; + this.model_name = model_name; + this.user_id = user_id; + this.user_name = user_name; + this.real_name = real_name; + this.login_ip = login_ip; + this.summary = summary; + } + @Override + public String toString() { + return "UserOptLog [id=" + id + ", title=" + title + ", app_name=" + + app_name + ", model_name=" + model_name + ", log_content=" + + log_content + ", log_type=" + log_type + ", user_id=" + + user_id + ", user_name=" + user_name + ", real_name=" + + real_name + ", login_ip=" + login_ip + ", summary=" + summary + + "]"; + } + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public String getTitle() { + return title; + } + public void setTitle(String title) { + this.title = title; + } + public String getApp_name() { + return app_name; + } + public void setApp_name(String app_name) { + this.app_name = app_name; + } + public String getModel_name() { + return model_name; + } + public void setModel_name(String model_name) { + this.model_name = model_name; + } + public String getLog_content() { + return log_content; + } + public void setLog_content(String log_content) { + this.log_content = log_content; + } + public String getLog_type() { + return log_type; + } + public void setLog_type(String log_type) { + this.log_type = log_type; + } + public String getUser_id() { + return user_id; + } + public void setUser_id(String user_id) { + this.user_id = user_id; + } + public String getUser_name() { + return user_name; + } + public void setUser_name(String user_name) { + this.user_name = user_name; + } + public String getReal_name() { + return real_name; + } + public void setReal_name(String real_name) { + this.real_name = real_name; + } + public String getLogin_ip() { + return login_ip; + } + public void setLogin_ip(String login_ip) { + this.login_ip = login_ip; + } + public String getSummary() { + return summary; + } + public void setSummary(String summary) { + this.summary = summary; + } +} diff --git a/src/main/java/com/gzzn/omms/adminapi/domain/primary/dao/settings/UisettingsDao.java b/src/main/java/com/gzzn/omms/adminapi/domain/primary/dao/settings/UisettingsDao.java index 8f6700d..6d7afd7 100644 --- a/src/main/java/com/gzzn/omms/adminapi/domain/primary/dao/settings/UisettingsDao.java +++ b/src/main/java/com/gzzn/omms/adminapi/domain/primary/dao/settings/UisettingsDao.java @@ -1,7 +1,9 @@ package com.gzzn.omms.adminapi.domain.primary.dao.settings; import java.util.List; + import org.springframework.data.repository.CrudRepository; + import com.gzzn.omms.adminapi.domain.primary.entity.settings.Uisettings; public interface UisettingsDao extends CrudRepository{ @@ -17,4 +19,6 @@ public interface UisettingsDao extends CrudRepository{ //保存 Uisettings save(Uisettings uisettings); + + Uisettings findByUserid(String userid); } \ No newline at end of file diff --git a/src/main/java/com/gzzn/omms/adminapi/domain/primary/entity/settings/Uisettings.java b/src/main/java/com/gzzn/omms/adminapi/domain/primary/entity/settings/Uisettings.java index d89eb65..61d4ba7 100644 --- a/src/main/java/com/gzzn/omms/adminapi/domain/primary/entity/settings/Uisettings.java +++ b/src/main/java/com/gzzn/omms/adminapi/domain/primary/entity/settings/Uisettings.java @@ -25,6 +25,7 @@ public class Uisettings implements Serializable { @Column(name="setting_content") private String settingContent; //具体的设置内容,json格式的设置内容。不超过60KB + @Column(name="userid") private String userid; //用户id public Uisettings() { diff --git a/src/main/java/com/gzzn/omms/adminapi/dto/EsPage.java b/src/main/java/com/gzzn/omms/adminapi/dto/EsPage.java new file mode 100644 index 0000000..2b68678 --- /dev/null +++ b/src/main/java/com/gzzn/omms/adminapi/dto/EsPage.java @@ -0,0 +1,84 @@ +package com.gzzn.omms.adminapi.dto; + +import java.util.List; +import java.util.Map; + +import lombok.Data; +import lombok.ToString; + +@Data +@ToString +public class EsPage { + + /** + * 当前页 + */ + private int currentPage; + /** + * 每页显示多少条 + */ + private int pageSize; + + /** + * 总记录数 + */ + private int recordCount; + /** + * 本页的数据列表 + */ + private List> recordList; + + /** + * 总页数 + */ + private int pageCount; + /** + * 页码列表的开始索引(包含) + */ + private int beginPageIndex; + /** + * 页码列表的结束索引(包含) + */ + private int endPageIndex; + + /** + * 只接受前4个必要的属性,会自动的计算出其他3个属性的值 + * + * @param currentPage + * @param pageSize + * @param recordCount + * @param recordList + */ + public EsPage(int currentPage, int pageSize, int recordCount, List> recordList) { + this.currentPage = currentPage; + this.pageSize = pageSize; + this.recordCount = recordCount; + this.recordList = recordList; + + // 计算总页码 + pageCount = (recordCount + pageSize - 1) / pageSize; + + // 计算 beginPageIndex 和 endPageIndex + // >> 总页数不多于10页,则全部显示 + if (pageCount <= 10) { + beginPageIndex = 1; + endPageIndex = pageCount; + } + // 总页数多于10页,则显示当前页附近的共10个页码 + else { + // 当前页附近的共10个页码(前4个 + 当前页 + 后5个) + beginPageIndex = currentPage - 4; + endPageIndex = currentPage + 5; + // 当前面的页码不足4个时,则显示前10个页码 + if (beginPageIndex < 1) { + beginPageIndex = 1; + endPageIndex = 10; + } + // 当后面的页码不足5个时,则显示后10个页码 + if (endPageIndex > pageCount) { + endPageIndex = pageCount; + beginPageIndex = pageCount - 10 + 1; + } + } + } +} diff --git a/src/main/java/com/gzzn/omms/adminapi/service/IUserService.java b/src/main/java/com/gzzn/omms/adminapi/service/IUserService.java index 37112e4..40edde6 100644 --- a/src/main/java/com/gzzn/omms/adminapi/service/IUserService.java +++ b/src/main/java/com/gzzn/omms/adminapi/service/IUserService.java @@ -1,6 +1,14 @@ package com.gzzn.omms.adminapi.service; +import java.net.InetSocketAddress; + public interface IUserService { String getCurrentUserId();//获取当前用户id String getCurrentUserName();//获取当前用户名 + /** + * 获取当前用户的远程真实地址信息(在网关的requet header中获取) + * @return + */ + InetSocketAddress getUserRemoteAddress();//获取当前用户的远程真实地址信息 + String getCurrentUserRealName(); } diff --git a/src/main/java/com/gzzn/omms/adminapi/service/impl/UserServiceImpl.java b/src/main/java/com/gzzn/omms/adminapi/service/impl/UserServiceImpl.java index bc21de0..bf19781 100644 --- a/src/main/java/com/gzzn/omms/adminapi/service/impl/UserServiceImpl.java +++ b/src/main/java/com/gzzn/omms/adminapi/service/impl/UserServiceImpl.java @@ -3,6 +3,7 @@ package com.gzzn.omms.adminapi.service.impl; import java.io.IOException; +import java.net.InetSocketAddress; import javax.servlet.http.HttpServletRequest; @@ -10,6 +11,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; import sun.misc.BASE64Decoder; @@ -38,6 +40,11 @@ public class UserServiceImpl implements IUserService { //获取网关header中传递的用户信息 private HeaderUserDto getHeaderUserDto() { +// HeaderUserDto dto = new HeaderUserDto(); +// dto.setUserId("00000000000000000000000000000000"); +// dto.setUserName("admin"); +// dto.setRealName("超级管理员"); +// return dto; try { String userStr = request.getHeader("user"); @@ -57,4 +64,35 @@ public class UserServiceImpl implements IUserService { throw new RuntimeException("header userinfo error!"+e.getMessage()); } } + + + @Override + public InetSocketAddress getUserRemoteAddress() { + try + { + String remoteAddress = request.getHeader("remoteAddress"); + logger.info("gateway-User-remoteAddress:"+remoteAddress); + if(StringUtils.isEmpty(remoteAddress)) + { + logger.warn("gateway-User-remoteAddress is null!"); + return null; + } + BASE64Decoder base64Decoder = new BASE64Decoder(); + byte[] bt = base64Decoder.decodeBuffer(remoteAddress); + + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.readValue(bt, InetSocketAddress.class); + } + catch (IOException e) + { + logger.error("gateway-Header-User-remoteAddres error!"+e.getMessage()); + throw new RuntimeException("gateway-Header-User-remoteAddres error!"+e.getMessage()); + } + } + + + @Override + public String getCurrentUserRealName() { + return this.getHeaderUserDto().getRealName(); + } } diff --git a/src/main/java/com/gzzn/omms/adminapi/utils/ElasticsearchUtil.java b/src/main/java/com/gzzn/omms/adminapi/utils/ElasticsearchUtil.java new file mode 100644 index 0000000..7431e37 --- /dev/null +++ b/src/main/java/com/gzzn/omms/adminapi/utils/ElasticsearchUtil.java @@ -0,0 +1,400 @@ +package com.gzzn.omms.adminapi.utils; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.annotation.PostConstruct; + +import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; +import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse; +import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest; +import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse; +import org.elasticsearch.action.delete.DeleteResponse; +import org.elasticsearch.action.get.GetRequestBuilder; +import org.elasticsearch.action.get.GetResponse; +import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.search.SearchRequestBuilder; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.action.search.SearchType; +import org.elasticsearch.action.update.UpdateRequest; +import org.elasticsearch.client.transport.TransportClient; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.text.Text; +import org.elasticsearch.common.transport.TransportAddress; +import org.elasticsearch.index.query.QueryBuilder; +import org.elasticsearch.search.SearchHit; +import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; +import org.elasticsearch.search.sort.SortOrder; +import org.elasticsearch.transport.client.PreBuiltTransportClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import com.alibaba.fastjson.JSONObject; +import com.gzzn.omms.adminapi.dto.EsPage; + +@Component +public class ElasticsearchUtil { + + private static final Logger LOGGER = LoggerFactory.getLogger(ElasticsearchUtil.class); + + /** + * elk集群地址 + */ + @Value("${elasticsearch.ip}") + private String hostName; + /** + * 端口 + */ + @Value("${elasticsearch.port}") + private String port; + /** + * 集群名称 + */ + @Value("${elasticsearch.cluster.name}") + private String clusterName; + /** + * 连接池 + */ + @Value("${elasticsearch.pool}") + private String poolSize; + + private static TransportClient client; + + /** + * @PostContruct是spring框架的注解 spring容器初始化的时候执行该方法 + */ + @SuppressWarnings("resource") + @PostConstruct + public void init() { +// client = this.transportClient; + try { + Settings settings = Settings.builder() + .put("cluster.name", clusterName) //集群名字 + .put("client.transport.sniff", true)//增加嗅探机制,找到ES集群 + .put("thread_pool.search.size", Integer.parseInt(poolSize))//增加线程池个数,暂时设为5 + .build(); + client = new PreBuiltTransportClient(settings) + .addTransportAddresses(new TransportAddress(InetAddress.getByName(hostName), Integer.valueOf(port))); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + } + + /** + * 创建索引 + * + * @param index + * @return + */ + public static boolean createIndex(String index) { + if (!isIndexExist(index)) { + LOGGER.info("Index is not exits!"); + } + CreateIndexResponse indexresponse = client.admin().indices().prepareCreate(index).execute().actionGet(); + LOGGER.info("执行建立成功?" + indexresponse.isAcknowledged()); + return indexresponse.isAcknowledged(); + } + + /** + * 删除索引 + * + * @param index + * @return + */ + public static boolean deleteIndex(String index) { + if (!isIndexExist(index)) { + LOGGER.info("Index is not exits!"); + } + DeleteIndexResponse dResponse = client.admin().indices().prepareDelete(index).execute().actionGet(); + if (dResponse.isAcknowledged()) { + LOGGER.info("delete index " + index + " successfully!"); + } else { + LOGGER.info("Fail to delete index " + index); + } + return dResponse.isAcknowledged(); + } + + /** + * 判断索引是否存在 + * + * @param index + * @return + */ + public static boolean isIndexExist(String index) { + IndicesExistsResponse inExistsResponse = client.admin().indices().exists(new IndicesExistsRequest(index)).actionGet(); + if (inExistsResponse.isExists()) { + LOGGER.info("Index [" + index + "] is exist!"); + } else { + LOGGER.info("Index [" + index + "] is not exist!"); + } + return inExistsResponse.isExists(); + } + + /** + * @Author: LX + * @Description: 判断inde下指定type是否存在 + * @Date: 2018/11/6 14:46 + * @Modified by: + */ + public boolean isTypeExist(String index, String type) { + return isIndexExist(index) + ? client.admin().indices().prepareTypesExists(index).setTypes(type).execute().actionGet().isExists() + : false; + } + + /** + * 数据添加,正定ID + * + * @param jsonObject 要增加的数据 + * @param index 索引,类似数据库 + * @param type 类型,类似表 + * @param id 数据ID + * @return + */ + public static String addData(JSONObject jsonObject, String index, String type, String id) { + IndexResponse response = client.prepareIndex(index, type, id).setSource(jsonObject).get(); + LOGGER.info("addData response status:{},id:{}", response.status().getStatus(), response.getId()); + return response.getId(); + } + + /** + * 数据添加 + * + * @param jsonObject 要增加的数据 + * @param index 索引,类似数据库 + * @param type 类型,类似表 + * @return + */ + public static String addData(JSONObject jsonObject, String index, String type) { + return addData(jsonObject, index, type, CommonUtils.getUUID32()); + } + + /** + * 通过ID删除数据 + * + * @param index 索引,类似数据库 + * @param type 类型,类似表 + * @param id 数据ID + */ + public static void deleteDataById(String index, String type, String id) { + + DeleteResponse response = client.prepareDelete(index, type, id).execute().actionGet(); + + LOGGER.info("deleteDataById response status:{},id:{}", response.status().getStatus(), response.getId()); + } + + /** + * 通过ID 更新数据 + * + * @param jsonObject 要增加的数据 + * @param index 索引,类似数据库 + * @param type 类型,类似表 + * @param id 数据ID + * @return + */ + public static void updateDataById(JSONObject jsonObject, String index, String type, String id) { + + UpdateRequest updateRequest = new UpdateRequest(); + + updateRequest.index(index).type(type).id(id).doc(jsonObject); + + client.update(updateRequest); + + } + + /** + * 通过ID获取数据 + * + * @param index 索引,类似数据库 + * @param type 类型,类似表 + * @param id 数据ID + * @param fields 需要显示的字段,逗号分隔(缺省为全部字段) + * @return + */ + public static Map searchDataById(String index, String type, String id, String fields) { + + GetRequestBuilder getRequestBuilder = client.prepareGet(index, type, id); + + if (!StringUtils.isEmpty(fields)) { + getRequestBuilder.setFetchSource(fields.split(","), null); + } + + GetResponse getResponse = getRequestBuilder.execute().actionGet(); + + return getResponse.getSource(); + } + + + /** + * 使用分词查询,并分页 + * + * @param index 索引名称 + * @param type 类型名称,可传入多个type逗号分隔 + * @param startPage 当前页 + * @param pageSize 每页显示条数 + * @param query 查询条件 + * @param fields 需要显示的字段,逗号分隔(缺省为全部字段) + * @param sortField 排序字段 + * @param highlightField 高亮字段 + * @return + */ + public static EsPage searchDataPage(String index, String type, int startPage, int pageSize, QueryBuilder query, String fields, String sortField, String highlightField) { + SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index); + if (!StringUtils.isEmpty(type)) { + searchRequestBuilder.setTypes(type.split(",")); + } + searchRequestBuilder.setSearchType(SearchType.QUERY_THEN_FETCH); + + // 需要显示的字段,逗号分隔(缺省为全部字段) + if (!StringUtils.isEmpty(fields)) { + searchRequestBuilder.setFetchSource(fields.split(","), null); + } + + //排序字段 + if (!StringUtils.isEmpty(sortField)) { + searchRequestBuilder.addSort(sortField, SortOrder.DESC); + } + + // 高亮(xxx=111,aaa=222) + if (!StringUtils.isEmpty(highlightField)) { + HighlightBuilder highlightBuilder = new HighlightBuilder(); + + //highlightBuilder.preTags("");//设置前缀 + //highlightBuilder.postTags("");//设置后缀 + + // 设置高亮字段 + highlightBuilder.field(highlightField); + searchRequestBuilder.highlighter(highlightBuilder); + } + + //searchRequestBuilder.setQuery(QueryBuilders.matchAllQuery()); + searchRequestBuilder.setQuery(query); + + // 分页应用 + searchRequestBuilder.setFrom(startPage).setSize(pageSize); + + // 设置是否按查询匹配度排序 + searchRequestBuilder.setExplain(true); + + //打印的内容 可以在 Elasticsearch head 和 Kibana 上执行查询 + LOGGER.info("\n{}", searchRequestBuilder); + + // 执行搜索,返回搜索响应信息 + SearchResponse searchResponse = searchRequestBuilder.execute().actionGet(); + + long totalHits = searchResponse.getHits().totalHits; + long length = searchResponse.getHits().getHits().length; + + LOGGER.debug("共查询到[{}]条数据,处理数据条数[{}]", totalHits, length); + + if (searchResponse.status().getStatus() == 200) { + // 解析对象 + List> sourceList = setSearchResponse(searchResponse, highlightField); + + return new EsPage(startPage, pageSize, (int) totalHits, sourceList); + } + + return null; + + } + + + /** + * 使用分词查询 + * + * @param index 索引名称 + * @param type 类型名称,可传入多个type逗号分隔 + * @param query 查询条件 + * @param size 文档大小限制 + * @param fields 需要显示的字段,逗号分隔(缺省为全部字段) + * @param sortField 排序字段 + * @param highlightField 高亮字段 + * @return + */ + public static List> searchListData( + String index, String type, QueryBuilder query, Integer size, + String fields, String sortField, String highlightField) { + + SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index); + if (!StringUtils.isEmpty(type)) { + searchRequestBuilder.setTypes(type.split(",")); + } + + if (!StringUtils.isEmpty(highlightField)) { + HighlightBuilder highlightBuilder = new HighlightBuilder(); + // 设置高亮字段 + highlightBuilder.field(highlightField); + searchRequestBuilder.highlighter(highlightBuilder); + } + + searchRequestBuilder.setQuery(query); + + if (!StringUtils.isEmpty(fields)) { + searchRequestBuilder.setFetchSource(fields.split(","), null); + } + searchRequestBuilder.setFetchSource(true); + + if (!StringUtils.isEmpty(sortField)) { + searchRequestBuilder.addSort(sortField, SortOrder.DESC); + } + + if (size != null && size > 0) { + searchRequestBuilder.setSize(size); + } + + //打印的内容 可以在 Elasticsearch head 和 Kibana 上执行查询 + LOGGER.info("\n{}", searchRequestBuilder); + + SearchResponse searchResponse = searchRequestBuilder.execute().actionGet(); + + long totalHits = searchResponse.getHits().totalHits; + long length = searchResponse.getHits().getHits().length; + + LOGGER.info("共查询到[{}]条数据,处理数据条数[{}]", totalHits, length); + + if (searchResponse.status().getStatus() == 200) { + // 解析对象 + return setSearchResponse(searchResponse, highlightField); + } + return null; + + } + + + /** + * 高亮结果集 特殊处理 + * + * @param searchResponse + * @param highlightField + */ + private static List> setSearchResponse(SearchResponse searchResponse, String highlightField) { + List> sourceList = new ArrayList>(); + StringBuffer stringBuffer = new StringBuffer(); + + for (SearchHit searchHit : searchResponse.getHits().getHits()) { + searchHit.getSourceAsMap().put("id", searchHit.getId()); + + if (!StringUtils.isEmpty(highlightField)) { + + System.out.println("遍历 高亮结果集,覆盖 正常结果集" + searchHit.getSourceAsMap()); + Text[] text = searchHit.getHighlightFields().get(highlightField).getFragments(); + + if (text != null) { + for (Text str : text) { + stringBuffer.append(str.string()); + } + //遍历 高亮结果集,覆盖 正常结果集 + searchHit.getSourceAsMap().put(highlightField, stringBuffer.toString()); + } + } + sourceList.add(searchHit.getSourceAsMap()); + } + return sourceList; + } +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 5079fe5..0c7915e 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -18,4 +18,14 @@ spring: tomcat: max-active: 30 test-on-borrow: true - initial-size: 3 \ No newline at end of file + initial-size: 3 + +# Elasticsearch +# 9200端口是用来让HTTP REST API来访问ElasticSearch,而9300端口是传输层监听的默认端口 +elasticsearch: + ip: 130.120.3.233 + port: 9300 + pool: 5 + #注意cluster.name需要与config/elasticsearch.yml中的cluster.name一致 + cluster: + name: docker-cluster \ No newline at end of file