springboot集成elasticsearch进行高亮查询

环境:

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);
    }
}

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值