环境:
windows+jdk1.8
springboot2.1.7
elasticsearch6.2.2.jar
elasticsearch5.6.16客户端
pom.xml
<spring-boot.version>2.1.7.RELEASE</spring-boot.version>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<version>${spring-boot.version}</version>
</dependency>
直接上代码:
yml
spring:
datasource:
url:
username:
password:
showsql : true
filters: wall,mergeStat
type: com.alibaba.druid.pool.DruidDataSource
redis:
#redis使用开关
use: true
database: 1
host: localhost
port: 6379
#jedis pool连接池的配置
jedis:
pool:
max-active: 1024
max-idle: 100
min-idle: 0
max-wait: -1
password:
timeout: 10000
data:
elasticsearch:
repositories:
enabled: true
cluster-name: elasticsearch
cluster-nodes: 127.0.0.1:9300 #9200是图形界面端,9300代码
EsArticleBean.java
package net.mingsoft.cms.es;
import lombok.experimental.Accessors;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import java.util.Date;
@Accessors(chain = true)
@Document(indexName = "esarticle", type = "esarticles")
public class EsArticleBean {
@Id
private String id;
/**
* 标题
*/
private String title;
/**
* 内容
*/
private String content;
/**
* 类型
*/
private String type;
/**
* es查询类型
*/
private String esType;
/**
* 作者
*/
private String author;
/**
* 跳转链接地址
*/
private String url;
/**
* 时间
*/
private String date;
/**
* 发文字号
*/
private String wjbh;
/**
* 公文种类
* */
private String wjType;
public String getWjbh() {
return wjbh;
}
public void setWjbh(String wjbh) {
this.wjbh = wjbh;
}
public String getWjType() {
return wjType;
}
public void setWjType(String wjType) {
this.wjType = wjType;
}
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 getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getEsType() {
return esType;
}
public void setEsType(String esType) {
this.esType = esType;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public EsArticleBean(){
}
public EsArticleBean(String id, String title, String content, String type, String esType, String author, String url, String date) {
this.id = id;
this.title = title;
this.content = content;
this.type = type;
this.esType = esType;
this.author = author;
this.url = url;
this.date = date;
}
@Override
public String toString() {
return "EsArticleBean{" +
"id='" + id + '\'' +
", title='" + title + '\'' +
", content='" + content + '\'' +
", type='" + type + '\'' +
", esType='" + esType + '\'' +
", author='" + author + '\'' +
", url='" + url + '\'' +
", date='" + date + '\'' +
'}';
}
}
EsArticleController.java
package net.mingsoft.cms.es;
import io.swagger.annotations.*;
import net.mingsoft.site.model.Sensitive;
import net.mingsoft.site.model.SensitiveExample;
import net.mingsoft.site.service.SiteSensitiveService;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
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.data.domain.*;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.web.bind.annotation.*;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
@Api("es查询服务")
@RestController
@RequestMapping("/esArticle")
public class EsArticleController {
@Autowired
private EsArticleService esArticleService;
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
@Autowired
private SiteSensitiveService siteSensitiveService;
/**
* 全文搜索判断敏感词
* @param keyword 关键字
* @return {@link } 接收到的数据格式为json
*/
@GetMapping("/sensitiveFlag")
@ApiOperation(value = "判断输入的内容是否为敏感词")
@ApiImplicitParams({
@ApiImplicitParam(name = "keyword", value = "关键字", required = false,paramType="query"),
})
public boolean sensitiveFlag(String keyword){
if(StringUtils.isEmpty(keyword)){
return true;
}
List<Sensitive> list = siteSensitiveService.selectByExample(new SensitiveExample());
boolean flag = true;
if(null != list && !list.isEmpty()){
for(Sensitive s : list){
if(s.getName().equals(keyword)){
flag = false;
break;
}
}
}
if(!flag){
return false;
}
return true;
}
/**
* 全文搜索
* @param keyword 关键字
* @param pageNumber 当前页,从0开始
* @param pageSize 每页大小
* @return {@link } 接收到的数据格式为json
*/
@GetMapping("/queryEsArticle")
@ApiOperation(value = "es分页查询方法")
@ApiImplicitParams({
@ApiImplicitParam(name = "pageNumber", value = "页数(第一页传0)", required = true,paramType="query"),
@ApiImplicitParam(name = "pageSize", value = "每页的数量(一般为10或20)", required = true,paramType="query"),
@ApiImplicitParam(name = "keyword", value = "标题和内容的关键字", required = false,paramType="query"),
@ApiImplicitParam(name = "esType", value = "es查询类型,传类型的编码(文件:esWJ,资讯:esZX,公报;esGB,其他:esQT)", required = false,paramType="query"),
@ApiImplicitParam(name = "dateType", value = "时间查询类型(0:一周,1:一个月,2:三个月)", required = false,paramType="query"),
})
public Page<EsArticleBean> queryEsArticle(int pageNumber,
int pageSize,String keyword,String esType,String dateType) {
// if size is null, size default 10
if (0 == pageSize){
pageSize = 10;
}
//在此处判断用户输入的keyword中是否有敏感词
BoolQueryBuilder builder = QueryBuilders.boolQuery();
if (!StringUtils.isEmpty(keyword)) {
builder.must(QueryBuilders.multiMatchQuery(keyword, "title", "content"));
}
if (!StringUtils.isEmpty(esType)) {
builder.must(QueryBuilders.matchQuery("esType",esType));
}
//dateType 0:一周,1:一个月,2:三个月
if (!StringUtils.isEmpty(dateType)) {
Calendar c = Calendar.getInstance();
if("0".equals(dateType)){
//当前时间年月日
c.add(Calendar.DATE, - 7);
Date time = c.getTime();
builder.must(rangeQuery("date").gte(time.getTime()));
}else if("1".equals(dateType)){
c.add(Calendar.DATE, - 30);
Date time = c.getTime();
builder.must(rangeQuery("date").gte(time.getTime()));
}else if("2".equals(dateType)){
c.add(Calendar.DATE, - 90);
Date time = c.getTime();
builder.must(rangeQuery("date").gte(time.getTime()));
}
}
// 构造分页类
Pageable pageable = PageRequest.of(pageNumber, pageSize);
String preTag = "<font color='#dd4b39'>";//google的色值
String postTag = "</font>";
SearchQuery searchQuery = new NativeSearchQueryBuilder().
withQuery(builder).
withHighlightFields(
new HighlightBuilder.Field("title").preTags(preTag).postTags(postTag),
new HighlightBuilder.Field("content").preTags(preTag).postTags(postTag)
//,new HighlightBuilder.Field("esType").preTags(preTag).postTags(postTag)
).build();
searchQuery.setPageable(pageable);
// 不需要高亮直接return ideas
// AggregatedPage<Idea> ideas = elasticsearchTemplate.queryForPage(searchQuery, Idea.class);
// 高亮字段
AggregatedPage<EsArticleBean> ideas = elasticsearchTemplate.queryForPage(searchQuery, EsArticleBean.class, new SearchResultMapper() {
@Override
public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
List<EsArticleBean> chunk = new ArrayList<>();
for (SearchHit searchHit : response.getHits()) {
EsArticleBean bean = new EsArticleBean();
if (response.getHits().getHits().length <= 0) {
return null;
}
bean = hitToEntity(searchHit);
//name or memoe
HighlightField title = searchHit.getHighlightFields().get("title");
if (title != null) {
bean.setTitle(title.fragments()[0].toString());
}
HighlightField ideaContent = searchHit.getHighlightFields().get("content");
if (ideaContent != null) {
bean.setContent(ideaContent.fragments()[0].toString());
}
chunk.add(bean);
}
if (chunk.size() > 0) {
return new AggregatedPageImpl<>((List<T>) chunk,pageable,response.getHits().getTotalHits());
}else{
return new AggregatedPageImpl<>((List<T>) new ArrayList<>());
}
}
});
Page<EsArticleBean> pageData = ideas == null ? new PageImpl<>(new ArrayList<>(), pageable, 0) : new PageImpl<>(ideas.getContent(), pageable, ideas.getTotalElements());
return pageData;
}
/**
* 全文搜索政务公开
*/
@GetMapping("/queryEsArticleZWGK")
@ApiOperation(value = "es分页查询方法(政务公开)")
@ApiImplicitParams({
@ApiImplicitParam(name = "pageNumber", value = "页数(第一页传0)", required = true,paramType="query"),
@ApiImplicitParam(name = "pageSize", value = "每页的数量(一般为10或20)", required = true,paramType="query"),
@ApiImplicitParam(name = "title", value = "标题", required = false,paramType="query"),
@ApiImplicitParam(name = "content", value = "正文", required = false,paramType="query"),
@ApiImplicitParam(name = "wjType", value = "公文种类(洛政令,洛政,洛政办,洛政任,洛政土)", required = false,paramType="query"),
@ApiImplicitParam(name = "wjbh", value = "发文字号", required = false,paramType="query"),
@ApiImplicitParam(name = "year", value = "年份(如:2008)", required = false,paramType="query"),
@ApiImplicitParam(name = "dataTime", value = "发布日期(如:2008-08-08)", required = false,paramType="query"),
})
public Page<EsArticleBean> queryEsArticleZWGK(int pageNumber,
int pageSize,String title,String content,String wjType,String wjbh,String year,String dataTime) throws ParseException {
// if size is null, size default 10
if (0 == pageSize){
pageSize = 10;
}
//在此处判断用户输入的keyword中是否有敏感词
BoolQueryBuilder builder = QueryBuilders.boolQuery();
if (!StringUtils.isEmpty(title)) {
builder.must(QueryBuilders.multiMatchQuery(title, "title"));
}
if (!StringUtils.isEmpty(content)) {
builder.must(QueryBuilders.multiMatchQuery(content, "content"));
}
if (!StringUtils.isEmpty(wjType)) {
builder.must(QueryBuilders.multiMatchQuery(wjType, "wjType"));
}
if (!StringUtils.isEmpty(wjbh)) {
builder.must(QueryBuilders.multiMatchQuery(wjbh, "wjbh"));
}
//年份查询
if (!StringUtils.isEmpty(year) && isNumeric(year)) {
Long startTime = getYearStartTime(year);
Long endTime = getYearEndTime(String.valueOf(Integer.valueOf(year)+1));
builder.must(rangeQuery("date").gte(startTime).lte(endTime));
}
//年月日查询
if (!StringUtils.isEmpty(dataTime)) {
Long startTime = getTimeStartTime(dataTime);
Long endTime = getTimeEndTime(dataTime);
builder.must(rangeQuery("date").gte(startTime).lte(endTime));
}
// 构造分页类
Pageable pageable = PageRequest.of(pageNumber, pageSize);
String preTag = "<font color='#dd4b39'>";//google的色值
String postTag = "</font>";
SearchQuery searchQuery = new NativeSearchQueryBuilder().
withQuery(builder).
withHighlightFields(
new HighlightBuilder.Field("title").preTags(preTag).postTags(postTag),
new HighlightBuilder.Field("content").preTags(preTag).postTags(postTag)
//,new HighlightBuilder.Field("esType").preTags(preTag).postTags(postTag)
).build();
searchQuery.setPageable(pageable);
// 不需要高亮直接return ideas
// AggregatedPage<Idea> ideas = elasticsearchTemplate.queryForPage(searchQuery, Idea.class);
// 高亮字段
AggregatedPage<EsArticleBean> ideas = elasticsearchTemplate.queryForPage(searchQuery, EsArticleBean.class, new SearchResultMapper() {
@Override
public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
List<EsArticleBean> chunk = new ArrayList<>();
for (SearchHit searchHit : response.getHits()) {
EsArticleBean bean = new EsArticleBean();
if (response.getHits().getHits().length <= 0) {
return null;
}
bean = hitToEntity(searchHit);
//name or memoe
HighlightField title = searchHit.getHighlightFields().get("title");
if (title != null) {
bean.setTitle(title.fragments()[0].toString());
}
HighlightField ideaContent = searchHit.getHighlightFields().get("content");
if (ideaContent != null) {
bean.setContent(ideaContent.fragments()[0].toString());
}
chunk.add(bean);
}
if (chunk.size() > 0) {
return new AggregatedPageImpl<>((List<T>) chunk,pageable,response.getHits().getTotalHits());
}else{
return new AggregatedPageImpl<>((List<T>) new ArrayList<>());
}
}
});
Page<EsArticleBean> pageData = ideas == null ? new PageImpl<>(new ArrayList<>(), pageable, 0) : new PageImpl<>(ideas.getContent(), pageable, ideas.getTotalElements());
return pageData;
}
/**
* 利用正则表达式判断字符串是否是数字
* @param str
* @return
*/
public boolean isNumeric(String str){
Pattern pattern = Pattern.compile("[0-9]*");
Matcher isNum = pattern.matcher(str);
if( !isNum.matches() ){
return false;
}
return true;
}
/**
* 获取年的开始时间戳
*
* @param year 年份
* @return
*/
public static Long getYearStartTime(String year) throws ParseException {
DateFormat df = new SimpleDateFormat("yyyy");
Date date = df.parse(year);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
long tim = cal .getTimeInMillis();
return tim;
}
/**
* 获取当年的最后时间戳
*
* @return
*/
public static Long getYearEndTime(String year) throws ParseException {
DateFormat df = new SimpleDateFormat("yyyy");
Date date = df.parse(year);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
long tim = cal .getTimeInMillis();
return tim;
}
/**
* 获取日期的开始时间戳
*
* @param dateTime 年份
* @return
*/
public static Long getTimeStartTime(String dateTime) throws ParseException {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
Date date = df.parse(dateTime);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
long tim = cal .getTimeInMillis();
return tim;
}
/**
* 获取日期的结束时间戳
*
* @param dateTime 年份
* @return
*/
public static Long getTimeEndTime(String dateTime) throws ParseException {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
Date date = df.parse(dateTime);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.DATE, cal.get(Calendar.DATE) + 1);
long tim = cal .getTimeInMillis();
return tim;
}
private EsArticleBean hitToEntity(SearchHit searchHit) {
EsArticleBean EsArticleBean = new EsArticleBean();
EsArticleBean.setId(searchHit.getId() == null ? null : searchHit.getId());
EsArticleBean.setTitle(String.valueOf(searchHit.getSourceAsMap().get("title")));
EsArticleBean.setContent(String.valueOf(searchHit.getSourceAsMap().get("content")));
EsArticleBean.setType(String.valueOf(searchHit.getSourceAsMap().get("type")));
EsArticleBean.setEsType(String.valueOf(searchHit.getSourceAsMap().get("esType")));
EsArticleBean.setAuthor(String.valueOf(searchHit.getSourceAsMap().get("author")));
EsArticleBean.setUrl(String.valueOf(searchHit.getSourceAsMap().get("url")));
EsArticleBean.setDate(String.valueOf(searchHit.getSourceAsMap().get("date")));
return EsArticleBean;
}
}
EsArticleRepository.java
package net.mingsoft.cms.es;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Component;
/**
* @author duanxiaozhou
*/
@Component
public interface EsArticleRepository extends ElasticsearchRepository<EsArticleBean,String> {
Page<EsArticleBean> findByAuthor(String author, Pageable pageable);
Page<EsArticleBean> findByTitle(String title, Pageable pageable);
}
EsArticleService.java
package net.mingsoft.cms.es;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import java.util.List;
import java.util.Optional;
public interface EsArticleService {
Optional<EsArticleBean> findById(String id);
EsArticleBean save(EsArticleBean blog);
void delete(EsArticleBean blog);
Optional<EsArticleBean> findOne(String id);
Page<EsArticleBean> findByAuthor(String author, PageRequest pageRequest);
Page<EsArticleBean> findByTitle(String title, PageRequest pageRequest);
List<EsArticleBean> findAll();
}
EsArticleServiceImpl.java
package net.mingsoft.cms.es;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service("esArticleService")
public class EsArticleServiceImpl implements EsArticleService {
@Autowired
@Qualifier("esArticleRepository")
private EsArticleRepository articleRepository;
@Override
public Optional<EsArticleBean> findById(String id) {
//CrudRepository中的方法
return articleRepository.findById(id);
}
@Override
public EsArticleBean save(EsArticleBean blog) {
return articleRepository.save(blog);
}
@Override
public void delete(EsArticleBean blog) {
articleRepository.delete(blog);
}
@Override
public Optional<EsArticleBean> findOne(String id) {
return articleRepository.findById(id);
}
@Override
public List<EsArticleBean> findAll() {
return (List<EsArticleBean>) articleRepository.findAll();
}
@Override
public Page<EsArticleBean> findByAuthor(String author, PageRequest pageRequest) {
return articleRepository.findByAuthor(author,pageRequest);
}
@Override
public Page<EsArticleBean> findByTitle(String title, PageRequest pageRequest) {
return articleRepository.findByTitle(title,pageRequest);
}
}