package com.supwisdom.portal.service;
import com.alibaba.fastjson.JSON;
import com.supwisdom.portal.constant.CalendarConstant;
import com.supwisdom.portal.constant.SearchConstant;
import com.supwisdom.portal.dao.search.*;
import com.supwisdom.portal.model.search.*;
import com.supwisdom.portal.utils.UserUtil;
import com.supwisdom.portal.web.dto.SearchReq;
import com.supwisdom.portal.web.dto.SearchResp;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryStringQueryBuilder;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.SearchDocument;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* Created by jyl on 2020/5/20.
*/
@Service
@SuppressWarnings("all")
public class SearchService {
@Autowired
private RestHighLevelClient client;
@Autowired
private ScheduleESDao scheduleESDao;
@Autowired
private ContentESDao contentESDao;
@Autowired
private InformationESDao informationESDao;
@Autowired
private ServeESDao serveESDao;
@Autowired
private TaskESDao taskESDao;
@Autowired
ElasticsearchRestTemplate elasticsearchRestTemplate;
/**
* 根据关键字及相关条件获取所有服务
*/
public SearchResp getSearchAll(SearchReq req) throws Exception {
String terminalInfo = UserUtil.getUser().getTerminalInfo();
SearchRequest searchRequest = this.getSearchRequest(req.getKeyWordType());
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.aggregation(AggregationBuilders.terms("sumarray").field("_index"));
//模糊搜索
QueryStringQueryBuilder queryBuilder = this.getQueryStringQueryBuilder(req.getKeyWord(), req.getScope());
//构建高亮体
HighlightBuilder highlightBuilder = this.getHighlightBuilder(req.getScope());
highlightBuilder.requireFieldMatch(false);
//是否根据时间排序
if (CalendarConstant.IS_FORCE_SUBSCRIBED.equals(req.getOrderingRule())) {
searchSourceBuilder.sort("startDate", SortOrder.DESC);
}
//搜索体(添加多个搜索参数)
searchSourceBuilder.highlighter(highlightBuilder);
searchSourceBuilder.query(queryBuilder);
searchSourceBuilder.from(req.getPageIndex());
searchSourceBuilder.size(req.getItemsPerPage());
//是否根据时间范围过滤
BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("startDate");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
if (StringUtils.isNotBlank(req.getStartDate())) {
rangeQueryBuilder.gte(sdf.parse(req.getStartDate()).getTime());
}
if (StringUtils.isNotBlank(req.getStartDate())) {
rangeQueryBuilder.lte(sdf.parse(req.getEndDate()).getTime());
}
boolBuilder.must(rangeQueryBuilder);
//must(QueryBuilders.matchQuery("serveTerminal",terminalInfo))
} catch (Throwable e) {
e.printStackTrace();
throw new Exception("根据时间查询失败!");
}
searchSourceBuilder.postFilter(boolBuilder);
System.out.println("======================begin search:");
searchRequest.source(searchSourceBuilder);
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
System.out.println("======================end search:");
SearchResp resp = new SearchResp();
resp.setTotal(String.valueOf(response.getHits().getTotalHits().value));
resp.setList(this.getHit(response, req.getScope(), terminalInfo));
return resp;
}
/**
* 根据关键字及相关条件获取所有服务
*/
public SearchHits globalSearch(SearchReq req) throws Exception {
String terminalInfo = UserUtil.getUser().getTerminalInfo();
IndexCoordinates indexCoordinates = null;
switch (req.getKeyWordType()) {
case "0":
indexCoordinates = IndexCoordinates.of
("portal-serve", "portal-content", "portal-task", "portal-information", "portal-schedule");
break;
case "1":
indexCoordinates = IndexCoordinates.of
("portal-serve");
break;
case "2":
indexCoordinates = IndexCoordinates.of
("portal-task");
break;
case "3":
indexCoordinates = IndexCoordinates.of
("portal-information");
break;
case "4":
indexCoordinates = IndexCoordinates.of
("portal-content");
break;
case "5":
indexCoordinates = IndexCoordinates.of
("portal-schedule");
break;
}
//模糊搜索
QueryStringQueryBuilder queryBuilder = this.getQueryStringQueryBuilder(req.getKeyWord(), req.getScope());
//构建高亮体
HighlightBuilder highlightBuilder = this.getHighlightBuilder(req.getScope());
highlightBuilder.requireFieldMatch(false);
//是否根据时间范围过滤
BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("startDate");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
if (StringUtils.isNotBlank(req.getStartDate())) {
rangeQueryBuilder.gte(sdf.parse(req.getStartDate()).getTime());
}
if (StringUtils.isNotBlank(req.getStartDate())) {
rangeQueryBuilder.lte(sdf.parse(req.getEndDate()).getTime());
}
boolBuilder.must(rangeQueryBuilder);
//must(QueryBuilders.matchQuery("serveTerminal",terminalInfo))
} catch (Throwable e) {
e.printStackTrace();
throw new Exception("根据时间查询失败!");
}
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
nativeSearchQueryBuilder.withFilter(boolBuilder).withHighlightBuilder(highlightBuilder)
.withQuery(queryBuilder).withPageable(PageRequest.of(req.getPageIndex(), req.getItemsPerPage()));
//nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms("sumarray").field("_index"));
//是否根据时间排序
if (CalendarConstant.IS_FORCE_SUBSCRIBED.equals(req.getOrderingRule())) {
nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("startDate").order(SortOrder.DESC));
}
System.out.println("======================begin search v2:");
SearchHits response = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), SearchDocument.class, indexCoordinates);
System.out.println("======================end search v2:");
return response;
}
public HighlightBuilder getHighlightBuilder(String scope) {
HighlightBuilder highlightBuilder = new HighlightBuilder();
//查询标题
if (CalendarConstant.NO_OPTION.equals(scope)) {
highlightBuilder.field("informationName");
highlightBuilder.field("scheduleTitle");
highlightBuilder.field("serveName");
highlightBuilder.field("taskName");
highlightBuilder.field("title");
} else {
highlightBuilder.field("informationName");
highlightBuilder.field("scheduleTitle");
highlightBuilder.field("serveName");
highlightBuilder.field("taskName");
highlightBuilder.field("title");
highlightBuilder.field("contentMsg");
highlightBuilder.field("serveMsg");
highlightBuilder.field("taskMsg");
}
return highlightBuilder;
}
public QueryStringQueryBuilder getQueryStringQueryBuilder(String keyWord, String scope) {
QueryStringQueryBuilder queryBuilder = new QueryStringQueryBuilder("\"" + keyWord + "\"");
//查询标题
if (CalendarConstant.NO_OPTION.equals(scope)) {
queryBuilder.field("serveName");
queryBuilder.field("title");
queryBuilder.field("taskName");
queryBuilder.field("informationName");
queryBuilder.field("scheduleTitle");
} else {
queryBuilder.field("serveName");
queryBuilder.field("title");
queryBuilder.field("taskName");
queryBuilder.field("informationName");
queryBuilder.field("scheduleTitle");
queryBuilder.field("contentMsg");
queryBuilder.field("serveMsg");
queryBuilder.field("taskMsg");
}
return queryBuilder;
}
public SearchRequest getSearchRequest(String keyWordType) {
SearchRequest searchRequest = null;
switch (keyWordType) {
case "0":
searchRequest = new SearchRequest
("portal-serve", "portal-content", "portal-task", "portal-information", "portal-schedule");
break;
case "1":
searchRequest = new SearchRequest
("portal-serve");
break;
case "2":
searchRequest = new SearchRequest
("portal-task");
break;
case "3":
searchRequest = new SearchRequest
("portal-information");
break;
case "4":
searchRequest = new SearchRequest
("portal-content");
break;
case "5":
searchRequest = new SearchRequest
("portal-schedule");
break;
}
return searchRequest;
}
public List
实体类代码
package com.supwisdom.portal.model.search;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.Transient;
import java.util.Arrays;
import java.util.Date;
/**
* Created by jyl on 2020/5/22.
*
* 资讯相关请求类
*/
@ApiModel(value = "ES资讯相关类", description = "ES资讯请求类")
@Document(indexName = "portal-content", shards = 1, replicas = 0)
public class ContentES {
@ApiModelProperty(value = "资讯id", required = true)
@Id
private String contentId;
@ApiModelProperty(value = "发布时间", dataType = "Date", required = true)
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Field(type = FieldType.Date)
private Date startDate;
@ApiModelProperty(value = "文章标题", required = true)
@Field(analyzer = "ik_smart", type = FieldType.Text)
private String title;
@ApiModelProperty(value = "文章内容", required = true)
@Field(analyzer = "ik_smart", type = FieldType.Text)
private String contentMsg;
@ApiModelProperty(value = "发布者", required = true)
private String promulgator;
@ApiModelProperty(value = "发布单位", required = true)
private String releaseUnit;
@ApiModelProperty(value = "图片地址", required = true)
private String contentUrl;
@ApiModelProperty(value = "对应访问权限", required = true)
@Field(analyzer = "ik_smart", type = FieldType.Keyword)
private String[] permission;
@ApiModelProperty(hidden = true)
@Transient
private String type;
public String[] getPermission() {
return permission;
}
public void setPermission(String[] permission) {
this.permission = permission;
}
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public String getContentUrl() {
return contentUrl;
}
public void setContentUrl(String contentUrl) {
this.contentUrl = contentUrl;
}
public String getPromulgator() {
return promulgator;
}
public void setPromulgator(String promulgator) {
this.promulgator = promulgator;
}
public String getReleaseUnit() {
return releaseUnit;
}
public void setReleaseUnit(String releaseUnit) {
this.releaseUnit = releaseUnit;
}
public String getContentId() {
return contentId;
}
public void setContentId(String contentId) {
this.contentId = contentId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContentMsg() {
return contentMsg;
}
public void setContentMsg(String contentMsg) {
this.contentMsg = contentMsg;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
public String toString() {
return "ContentES{" +
"contentId='" + contentId + '\'' +
", startDate=" + startDate +
", title='" + title + '\'' +
", contentMsg='" + contentMsg + '\'' +
", promulgator='" + promulgator + '\'' +
", releaseUnit='" + releaseUnit + '\'' +
", contentUrl='" + contentUrl + '\'' +
", permission=" + Arrays.toString(permission) +
", type='" + type + '\'' +
'}';
}
}
package com.supwisdom.portal.model.search;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.Transient;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
* Created by jyl on 2020/5/23.
*/
@ApiModel(value = "ES服务相关类", description = "ES服务相关类")
@Document(indexName = "portal-serve", shards = 1, replicas = 0)
public class ServeES {
@ApiModelProperty(value = "服务id", required = true)
@Id
private String serveId;
@ApiModelProperty(value = "发布时间", dataType = "Date", required = true)
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Field(type = FieldType.Date)
private Date startDate;
@ApiModelProperty(value = "服务名称", required = true)
@Field(analyzer = "ik_smart", type = FieldType.Text)
private String serveName;
@ApiModelProperty(value = "所列字段", required = true)
@Field(analyzer = "ik_smart", type = FieldType.Text)
private List serveMsg;
@ApiModelProperty(value = "服务编号", required = true)
private String serveNum;
@ApiModelProperty(value = "服务来源", required = true)
@Field(analyzer = "ik_smart", type = FieldType.Text)
private String serveSource;
@ApiModelProperty(value = "服务图片地址", required = true)
@Field(type = FieldType.Text)
private String serveUrl;
@ApiModelProperty(value = "关联服务")
@Field(type = FieldType.Text)
private List serveRelevance;
@ApiModelProperty(value = "服务终端类型", required = true)
@Field(type = FieldType.Keyword)
private String[] serveTerminal;
@ApiModelProperty(value = "对应访问权限", required = true)
@Field(analyzer = "ik_smart",type = FieldType.Keyword)
private String[] permission;
@ApiModelProperty(hidden = true)
@Transient
private String type;
public String[] getPermission() {
return permission;
}
public void setPermission(String[] permission) {
this.permission = permission;
}
public String[] getServeTerminal() {
return serveTerminal;
}
public void setServeTerminal(String[] serveTerminal) {
this.serveTerminal = serveTerminal;
}
public String getType() {
return type;
}
public List getServeRelevance() {
return serveRelevance;
}
public void setServeRelevance(List serveRelevance) {
this.serveRelevance = serveRelevance;
}
public void setType(String type) {
this.type = type;
}
public String getServeNum() {
return serveNum;
}
public void setServeNum(String serveNum) {
this.serveNum = serveNum;
}
public String getServeSource() {
return serveSource;
}
public void setServeSource(String serveSource) {
this.serveSource = serveSource;
}
public String getServeUrl() {
return serveUrl;
}
public void setServeUrl(String serveUrl) {
this.serveUrl = serveUrl;
}
public String getServeId() {
return serveId;
}
public void setServeId(String serveId) {
this.serveId = serveId;
}
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public String getServeName() {
return serveName;
}
public void setServeName(String serveName) {
this.serveName = serveName;
}
public List getServeMsg() {
return serveMsg;
}
public void setServeMsg(List serveMsg) {
this.serveMsg = serveMsg;
}
@Override
public String toString() {
return "ServeES{" +
"serveId='" + serveId + '\'' +
", startDate=" + startDate +
", serveName='" + serveName + '\'' +
", serveMsg=" + serveMsg +
", serveNum='" + serveNum + '\'' +
", serveSource='" + serveSource + '\'' +
", serveUrl='" + serveUrl + '\'' +
", serveRelevance=" + serveRelevance +
", serveTerminal=" + Arrays.toString(serveTerminal) +
", permission=" + Arrays.toString(permission) +
", type='" + type + '\'' +
'}';
}
}
pom 依赖
org.springframework.boot spring-boot-starter-data-elasticsearch
es版本为7.7.0