1. 程式人生 > >ElasticSearch實戰:個人部落格搜尋和首頁內容展示

ElasticSearch實戰:個人部落格搜尋和首頁內容展示

前言

最近學習了SpringBoot,搞了一個小型部落格系統,在這個系統中的首頁內容展示、全文搜尋用到了elasticsearch。系統中持久層使用的是Springdata,但是沒有使用spring-data-elasticsearch,而是單獨引入的elasticsearch、transport依賴。下面就將我係統中涉及到的關於elasticsearch的程式碼貼出來、供大家一起學習。

準備環境

es中myBlog的mapping

    {  
        "settings":{  
             "analysis" : {  
                "analyzer
" : { "ik" : { "tokenizer" : "ik_max_word" } } }
}
, "mappings":{ "blog":{ "_all": { "enabled": true }, "properties
":{ "id":{ "type":"keyword" }, "blogId":{ "type":"keyword" }, "title":{ "type":"text", "analyzer": "ik_max_word"
}
, "summary":{ "type":"text", "analyzer": "ik_max_word" }, "content":{ "type":"text", "analyzer": "ik_max_word" }, "username":{ "type":"keyword" }, "avatar":{ "type":"keyword" }, "createTime":{ "type":"date" }, "readSize":{ "type":"integer" }, "commentSize":{ "type":"integer" }, "voteSize":{ "type":"integer" }, "tags":{ "type":"text", "analyzer": "ik_max_word" , "fielddata": true } }
}
}
}

引入依賴

<!-- es -->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>transport</artifactId>
            <version>5.5.2</version>
        </dependency>
        <dependency>
           <groupId>org.elasticsearch</groupId>
           <artifactId>elasticsearch</artifactId>
           <version>5.5.2</version>
        </dependency>

返回資料包裝類EsBlogVO:

public class EsBlogVO implements Serializable {

    private static final long serialVersionUID = 1L;

    private String id;

    private Long blogId; // Blog 的 id

    private String title;

    private String summary;

    private String content;

    private String username;

    private String avatar;

    private Timestamp createTime;

    private Integer readSize = 0; // 訪問量、閱讀量

    private Integer commentSize = 0; // 評論量

    private Integer voteSize = 0; // 點贊量

    private String tags; // 標籤  

    public EsBlogVO(){

    }

    public EsBlogVO(Blog blog){
        this.blogId = blog.getId();
        this.title = blog.getTitle();
        this.summary = blog.getSummary();
        this.content = blog.getContent();
        this.username = blog.getUser().getUsername();
        this.avatar = blog.getUser().getAvatar();
        this.createTime = blog.getCreateTime();
        this.readSize = blog.getReading();
        this.commentSize = blog.getCommentSize();
        this.voteSize = blog.getVoteSize();
        this.tags = blog.getTags();
    }

    public void update(Blog blog){
        this.blogId = blog.getId();
        this.title = blog.getTitle();
        this.summary = blog.getSummary();
        this.content = blog.getContent();
        this.username = blog.getUser().getUsername();
        this.avatar = blog.getUser().getAvatar();
        this.createTime = blog.getCreateTime();
        this.readSize = blog.getReading();
        this.commentSize = blog.getCommentSize();
        this.voteSize = blog.getVoteSize();
        this.tags = blog.getTags();
    }

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }

    public Long getBlogId() {
        return blogId;
    }
    public void setBlogId(Long blogId) {
        this.blogId = blogId;
    }

    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }

    public String getSummary() {
        return summary;
    }
    public void setSummary(String summary) {
        this.summary = summary;
    }

    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }

    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }

    public String getAvatar() {
        return avatar;
    }
    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }

    public Timestamp getCreateTime() {
        return createTime;
    }
    public void setCreateTime(Timestamp createTime) {
        this.createTime = createTime;
    }

    public Integer getReadSize() {
        return readSize;
    }
    public void setReadSize(Integer readSize) {
        this.readSize = readSize;
    }

    public Integer getCommentSize() {
        return commentSize;
    }
    public void setCommentSize(Integer commentSize) {
        this.commentSize = commentSize;
    }

    public Integer getVoteSize() {
        return voteSize;
    }
    public void setVoteSize(Integer voteSize) {
        this.voteSize = voteSize;
    }

    public String getTags() {
        return tags;
    }
    public void setTags(String tags) {
        this.tags = tags;
    }

    @Override
    public String toString() {
        return "EsBlogVO [id=" + id + ", blogId=" + blogId + ", title=" + title + ", summary=" + summary + ", content="
                + content + ", username=" + username + ", avatar=" + avatar + ", createTime=" + createTime
                + ", readSize=" + readSize + ", commentSize=" + commentSize + ", voteSize=" + voteSize + ", tags="
                + tags + "]";
    }

PageBean

系統中持久層用到的是SpringData框架,他有自己的Page,為了方便與前端pageHtml中的屬性不衝突,依照SpringData的page自己寫了一個PageBean

public class PageBean<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    //當前頁面
    private int number;
    //頁面大小
    private int size;
    //總頁數
    @SuppressWarnings("unused")  
    private int totalPages;
    //總記錄數
    private int totalElements;
    //是否是第一個
    @SuppressWarnings("unused")  
    private boolean first;
    //是否是最後一個
    @SuppressWarnings("unused")  
    private boolean last;
    //是否有上一頁
    @SuppressWarnings("unused")  
    private boolean hasPrevious;
    //是否有下一頁
    @SuppressWarnings("unused")  
    private boolean hasNext;
    //頁數位置
    @SuppressWarnings("unused")  
    private int offSet;

    private List<T> contentList;


    public PageBean() {

    }

    public PageBean(int number, int size) {
        super();
        this.number = number;
        this.size = size;
    }

    public PageBean(int number, int size, int totalElements) {
        super();
        this.number = number;
        this.size = size;
        this.totalElements = totalElements;
    }

    public int getNumber() {
        return number;
    }
    public void setNumber(int number) {
        this.number = number;
    }

    public int getSize() {
        return size;
    }
    public void setSize(int size) {
        this.size = size;
    }
    /**
     * 計算頁數
     * @return
     */
    public int getTotalPages() {
        return (int) Math.ceil((double) totalElements / (double) getSize());
    }
    public void setTotalPages(int totalPages) {
        this.totalPages = totalPages;
    }

    public int getTotalElements() {
        return totalElements;
    }
    public void setTotalElements(int totalElements) {
        this.totalElements = totalElements;
    }

    public boolean isFirst() {
        return !isHasPrevious();
    }
    public void setFirst(boolean first) {
        this.first = first;
    }
    /**
     * 計算位置
     * @return
     */
    public int getOffSet() {
        return this.number * this.size;
    }
    public void setOffSet(int offSet) {
        this.offSet = offSet;
    }

    public boolean isLast() {
        return !isHasNext();  
    }
    public void setLast(boolean last) {
        this.last = last;
    }

    public boolean isHasPrevious() {
        return getNumber() > 0;
    }
    public void setHasPrevious(boolean hasPrevious) {
        this.hasPrevious = hasPrevious;
    }

    public boolean isHasNext() {
        return (number == getTotalPages()) ? false : true;
    }
    public void setHasNext(boolean hasNext) {
        this.hasNext = hasNext;
    }

    public List<T> getContentList() {
        return contentList;
    }
    public void setContentList(List<T> contentList) {
        this.contentList = contentList;
    }
}

EsRepositity

部落格中涉及到的elastcisearch核心程式碼

@Component
public class EsBlogRepository {

    private static final String String = null;

    @Autowired
    private TransportClient client;

    @Autowired
    private UserRepository userRepository;

    /**
     * 根據id查詢document
     * @param id
     * @return
     * @throws InvocationTargetException 
     * @throws IllegalAccessException 
     * @throws ParseException 
     */
    public EsBlogVO getEsBlogByBlogId(Long blogId) throws IllegalAccessException, InvocationTargetException, ParseException {

        TermQueryBuilder termQuery = QueryBuilders.termQuery("blogId", blogId);

        SearchResponse searchResponse = this.client.prepareSearch("myblog")
                            .setTypes("blog")
                            .setSearchType(SearchType.DFS_QUERY_THEN_FETCH) //設定查詢型別:1.SearchType.DFS_QUERY_THEN_FETCH 精確查詢; 2.SearchType.SCAN 掃描查詢,無序
                            .setQuery(termQuery)
                            .get();

        EsBlogVO esBlogVo = null;
        for(SearchHit hit:searchResponse.getHits()) {
            //
            esBlogVo = new EsBlogVO();
            Map<String, Object> source = hit.getSource();
            //將id存放到Map中
            source.put("id", hit.getId());
            //轉化時間
            String date = (java.lang.String) source.get("createTime");

            if( date!=null && !(date.equals(""))) {
                 date = date.replace("Z", " UTC");//注意是空格+UTC
                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");//注意格式化的表示式
                    Date d = format.parse(date );
                    SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");    
                    String sdate=format2.format(d);        
                    Timestamp fTimestamp=Timestamp.valueOf(sdate);   
                    //將轉化後的時間存放到map中
                    source.put("createTime", fTimestamp);
            }
            //將map轉化為Bean
            BeanUtils.populate(esBlogVo, source);
            break;
        }
        System.out.println(esBlogVo);
        return esBlogVo;
    }
    /**
     * 刪除索引中的document
     * @param esBlogId
     */
    public void deleteEsBlog(String esBlogId) {
        DeleteResponse response = client.prepareDelete("myblog", "blog", esBlogId).get(); 
        Result result = response.getResult();
        System.out.println(result);
    }
    /**
     * 將document新增到索引中
     * @param blog
     * @throws IOException
     */
    public void addEsBlog(EsBlogVO blog) throws IOException {

        IndexResponse response = client.prepareIndex("myblog", "blog")  
                .setSource(XContentFactory.jsonBuilder()  
                        .startObject()  
                            .field("blogId", blog.getBlogId())  
                            .field("title", blog.getTitle())  
                            .field("summary",blog.getSummary())  
                            .field("content", blog.getContent())  
                            .field("username", blog.getUsername())  
                            .field("avatar", blog.getAvatar())  
                            .field("createTime",blog.getCreateTime())  
                            .field("readSize", blog.getReadSize())  
                            .field("commentSize", blog.getCommentSize())  
                            .field("voteSize", blog.getVoteSize())  
                            .field("tags",blog.getTags())  
                        .endObject())  
                .get();
        System.out.println(response.getResult()+","+response.getId());
    }
    /**
     * 修改索引中的document資料
     * @param blog
     * @throws IOException
     */
    public void updateEsblog(EsBlogVO blog) throws IOException {

        UpdateResponse response = client.prepareUpdate("myblog", "blog",blog.getId())  
                .setDoc(XContentFactory.jsonBuilder()  
                        .startObject()  
                        .field("blogId", blog.getBlogId())  
                        .field("title", blog.getTitle())  
                        .field("summary",blog.getSummary())  
                        .field("content", blog.getContent())  
                        .field("username", blog.getUsername())  
                        .field("avatar", blog.getAvatar())  
                        .field("createTime",blog.getCreateTime())  
                        .field("readSize", blog.getReadSize())  
                        .field("commentSize", blog.getCommentSize())  
                        .field("voteSize", blog.getVoteSize())  
                        .field("tags",blog.getTags())  
                        .endObject())  
                .get();  
        System.out.println(response.getResult());
    }
    /**
     * 查詢前三十個標籤
     * @return
     */
    public List<TagVO> listTop30tags(){
        List<TagVO> list = new ArrayList<>();
        //進行聚合查詢,terms按照某個欄位中進行分組  
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders  
                .terms("tags")    //aggs的名稱,自定義,取資料的時候與其一致即可  
                .field("tags")             //需要分組的欄位  
                .order(Terms.Order.count(false));  //true表asc按照doc_count排序,false表示desc排序       

        //查詢資料進行聚合分析  
        SearchResponse response = client.prepareSearch("myblog").setTypes("blog")  
                .addAggregation(termsAggregationBuilder)  
                .setSize(30)  
                .execute()  
                .actionGet();  
        //獲取聚合   
        StringTerms modelTerms = (StringTerms) response.getAggregations().asMap().get("tags");
        Iterator<Bucket> modelBucketIt = modelTerms.getBuckets().iterator();
        //遍歷桶
        while(modelBucketIt.hasNext()) {
             Bucket actiontypeBucket = modelBucketIt.next();
             list.add(new TagVO(actiontypeBucket.getKey().toString(),
                     actiontypeBucket.getDocCount()));

        }
        return list;
    }

    /**
     * 獲取前12個user
     * @return
     */
    public List<User> listTop12Users(){
        List<String> usernamelist = new ArrayList<>();
        //進行聚合查詢,terms按照某個欄位中進行分組  
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders  
                .terms("usernames")    //aggs的名稱,自定義,取資料的時候與其一致即可  
                .field("username")             //需要分組的欄位  
                .order(Terms.Order.count(false));  //true表asc按照doc_count排序,false表示desc排序       

        //查詢資料進行聚合分析  
        SearchResponse response = client.prepareSearch("myblog").setTypes("blog")  
                .addAggregation(termsAggregationBuilder)  
                .setSize(12)  
                .execute()  
                .actionGet();  
        //獲取聚合   
        StringTerms modelTerms = (StringTerms) response.getAggregations().asMap().get("usernames");
        Iterator<Bucket> modelBucketIt = modelTerms.getBuckets().iterator();
        //遍歷桶
        while(modelBucketIt.hasNext()) {
             Bucket actiontypeBucket = modelBucketIt.next();
             String username = actiontypeBucket.getKey().toString();
             usernamelist.add(username);
        }
        List<User> list = userRepository.findByUsernameIn(usernamelist);
        return list;
    }

    /**
     * 搜尋條件的總數
     * @param title
     * @param Summary
     * @param content
     * @param tags
     * @return
     */
    public Integer findTotalElementBySearchtxt(String title, String Summary, String content, String tags) {
        //建立bool查詢
        BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
        //使用should實現或者查詢
        boolBuilder.should(QueryBuilders.matchQuery("title",title));
        boolBuilder.should(QueryBuilders.matchQuery("summary",Summary));
        boolBuilder.should(QueryBuilders.matchQuery("content",content));
        boolBuilder.should(QueryBuilders.matchQuery("tags",tags));
        //查詢
        SearchRequestBuilder searchRequestBuilder = this.client.prepareSearch("myblog")
                .setTypes("blog")
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH) //設定查詢型別:1.SearchType.DFS_QUERY_THEN_FETCH 精確查詢; 2.SearchType.SCAN 掃描查詢,無序
                .setQuery(boolBuilder);
        //執行結果
        SearchResponse response = searchRequestBuilder.get();
        long totalHits = response.getHits().totalHits;
        return new Long(totalHits).intValue();
    }

    /**
     * 根據搜尋條件進行查詢,查詢結果高亮顯示,資料分頁
     * @param title
     * @param Summary
     * @param content
     * @param tags
     * @param pageable
     * @return
     * @throws ParseException 
     * @throws InvocationTargetException 
     * @throws IllegalAccessException 
     */
    public PageBean<EsBlogVO> findByTitleOrSummaryOrTagsOrContent(String title, String Summary, String content, String tags,
            PageBean<EsBlogVO> pageable) throws ParseException, IllegalAccessException, InvocationTargetException {

        //建立bool查詢
        BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
        //使用should實現或者查詢
        boolBuilder.should(QueryBuilders.matchQuery("title",title));
        boolBuilder.should(QueryBuilders.matchQuery("summary",Summary));
        boolBuilder.should(QueryBuilders.matchQuery("content",content));
        boolBuilder.should(QueryBuilders.matchQuery("tags",tags));
        //查詢
        SearchRequestBuilder searchRequestBuilder = this.client.prepareSearch("myblog")
                .setTypes("blog")
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH) //設定查詢型別:1.SearchType.DFS_QUERY_THEN_FETCH 精確查詢; 2.SearchType.SCAN 掃描查詢,無序
                .setQuery(boolBuilder)
                .setFrom(pageable.getOffSet())
                .setSize(pageable.getSize());
        // 設定高亮顯示
        HighlightBuilder highlightBuilder = new HighlightBuilder().field("*").requireFieldMatch(false);
        highlightBuilder.preTags("<span style=\"color:red\">");
        highlightBuilder.postTags("</span>");
        searchRequestBuilder.highlighter(highlightBuilder);
        // 執行結果
         //執行結果
        SearchResponse response = searchRequestBuilder.get();
        //接受結果
        List<EsBlogVO> result = new ArrayList<EsBlogVO>();

        //遍歷結果
        //SearchHits hits = response.getHits();
        for(SearchHit hits:response.getHits()){
            //例項化物件
            EsBlogVO esBlogVo = new EsBlogVO();
            //獲得查詢資料
            Map<String, Object> source = hits.getSource();
            //轉化時間
            String date = (java.lang.String) source.get("createTime");
            date = date.replace("Z", " UTC");//注意是空格+UTC
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");//注意格式化的表示式
            Date d = format.parse(date );
            SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");    
            String sdate=format2.format(d);        
            Timestamp fTimestamp=Timestamp.valueOf(sdate);   
            //將轉化後的時間存放到map中
            source.put("createTime", fTimestamp);
            //將map轉化為Bean
            BeanUtils.populate(esBlogVo, source);

            //處理高亮片段
            Map<String, HighlightField> highlightFields = hits.getHighlightFields();
            //title
            HighlightField titleField = highlightFields.get("title");
            if(titleField!=null){
                Text[] fragments = titleField.fragments();
                String titleTmp ="";
                for(Text text:fragments){
                    titleTmp+=text;
                }
                //將高亮片段組裝到結果中去
                esBlogVo.setTitle(titleTmp);
            }
            //summary
            HighlightField summary = highlightFields.get("summary");
            if(summary != null) {
                Text[] fragmentSummary = summary.fragments();
                String summaryTmp = "";
                for(Text sum:fragmentSummary) {
                    summaryTmp += sum;
                }
                esBlogVo.setSummary(summaryTmp);
            }
            //將查詢出來的結果放到集合當中
            result.add(esBlogVo);
        }
        pageable.setContentList(result);
        return pageable;
    }
    /**
     * 按最熱查詢
     * @param keyword
     * @param pageable
     * @return
     * @throws ParseException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public PageBean<EsBlogVO> listHotstEsBlogs(String keyword,PageBean<EsBlogVO> pageable) throws ParseException, IllegalAccessException, InvocationTargetException{
        //建立bool查詢
        BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
        //使用should實現或者查詢
        boolBuilder.should(QueryBuilders.matchQuery("title",keyword));
        boolBuilder.should(QueryBuilders.matchQuery("summary",keyword));
        boolBuilder.should(QueryBuilders.matchQuery("content",keyword));
        boolBuilder.should(QueryBuilders.matchQuery("tags",keyword));
        //設定排序
        FieldSortBuilder readSize = SortBuilders.fieldSort("readSize").order(SortOrder.DESC);
        FieldSortBuilder commentSize = SortBuilders.fieldSort("commentSize").order(SortOrder.DESC);
        FieldSortBuilder voteSize = SortBuilders.fieldSort("voteSize").order(SortOrder.DESC);
        FieldSortBuilder createTime = SortBuilders.fieldSort("createTime").order(SortOrder.DESC);

        //查詢
       SearchResponse searchResponse = this.client.prepareSearch("myblog")
                .setTypes("blog")
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH) //設定查詢型別:1.SearchType.DFS_QUERY_THEN_FETCH 精確查詢; 2.SearchType.SCAN 掃描查詢,無序
                .setQuery(boolBuilder)
                .addSort(readSize)
                .addSort(commentSize)
                .addSort(voteSize)
                .addSort(createTime)
                .setFrom(pageable.getOffSet())
                .setSize(pageable.getSize())
                .get();
        //列印語句
        System.out.println(searchResponse.toString());
        //接受結果
        List<EsBlogVO> result = new ArrayList<EsBlogVO>();
        for(SearchHit hits:searchResponse.getHits()){
            //例項化物件
            EsBlogVO esBlogVo = new EsBlogVO();
            //獲得查詢資料
            Map<String, Object> source = hits.getSource();
            //轉化時間
            String date = (java.lang.String) source.get("createTime");
            date = date.replace("Z", " UTC");//注意是空格+UTC
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");//注意格式化的表示式
            Date d = format.parse(date );
            SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");    
            String sdate=format2.format(d);        
            Timestamp fTimestamp=Timestamp.valueOf(sdate);   
            //將轉化後的時間存放到map中
            source.put("createTime", fTimestamp);
            //將map轉化為Bean
            BeanUtils.populate(esBlogVo, source);
            //將查詢出來的結果放到集合當中
            result.add(esBlogVo);
        }
        pageable.setContentList(result);
        return pageable;
    }

    /**
     * 按最新查詢
     * @param keyword
     * @param pageable
     * @return
     * @throws ParseException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public PageBean<EsBlogVO> listNewestEsBlogs(String keyword,PageBean<EsBlogVO> pageable) throws ParseException, IllegalAccessException, InvocationTargetException{
        //建立bool查詢
        BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
        //使用should實現或者查詢
        boolBuilder.should(QueryBuilders.matchQuery("title",keyword));
        boolBuilder.should(QueryBuilders.matchQuery("summary",keyword));
        boolBuilder.should(QueryBuilders.matchQuery("content",keyword));
        boolBuilder.should(QueryBuilders.matchQuery("tags",keyword));
        //設定排序
        FieldSortBuilder createTime = SortBuilders.fieldSort("createTime").order(SortOrder.DESC);

        //查詢
       SearchResponse searchResponse = this.client.prepareSearch("myblog")
                .setTypes("blog")
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH) //設定查詢型別:1.SearchType.DFS_QUERY_THEN_FETCH 精確查詢; 2.SearchType.SCAN 掃描查詢,無序
                .setQuery(boolBuilder)
                .addSort(createTime)
                .setFrom(pageable.getOffSet())
                .setSize(pageable.getSize())
                .get();
        //列印語句
        System.out.println(searchResponse.toString());
        //接受結果
        List<EsBlogVO> result = new ArrayList<EsBlogVO>();
        for(SearchHit hits:searchResponse.getHits()){
            //例項化物件
            EsBlogVO esBlogVo = new EsBlogVO();
            //獲得查詢資料
            Map<String, Object> source = hits.getSource();
            //轉化時間
            String date = (java.lang.String) source.get("createTime");
            date = date.replace("Z", " UTC");//注意是空格+UTC
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");//注意格式化的表示式
            Date d = format.parse(date );
            SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");    
            String sdate=format2.format(d);        
            Timestamp fTimestamp=Timestamp.valueOf(sdate);   
            //將轉化後的時間存放到map中
            source.put("createTime", fTimestamp);
            //將map轉化為Bean
            BeanUtils.populate(esBlogVo, source);
            //將查詢出來的結果放到集合當中
            result.add(esBlogVo);
        }
        pageable.setContentList(result);
        return pageable;
    }

    /**
     * 查詢document中最新的前5個
     * @param offset
     * @param pageSize
     * @return
     * @throws ParseException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public List<EsBlogVO> listnewTop5EsBlog (int offset,int pageSize) throws ParseException, IllegalAccessException, InvocationTargetException{
        //全文檢索
        MatchAllQueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();
        //設定排序
        FieldSortBuilder createTime = SortBuilders.fieldSort("createTime").order(SortOrder.DESC);

        //查詢
       SearchResponse searchResponse = this.client.prepareSearch("myblog")
                .setTypes("blog")
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH) //設定查詢型別:1.SearchType.DFS_QUERY_THEN_FETCH 精確查詢; 2.SearchType.SCAN 掃描查詢,無序
                .setQuery(matchAllQuery)
                .addSort(createTime)
                .setFrom(offset)
                .setSize(pageSize)
                .get();
        //列印語句
        System.out.println(searchResponse.toString());
        //接受結果
        List<EsBlogVO> result = new ArrayList<EsBlogVO>();
        for(SearchHit hits:searchResponse.getHits()){
            //例項化物件
            EsBlogVO esBlogVo = new EsBlogVO();
            //獲得查詢資料
            Map<String, Object> source = hits.getSource();
            //轉化時間
            String date = (java.lang.String) source.get("createTime");
            date = date.replace("Z", " UTC");//注意是空格+UTC
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");//注意格式化的表示式
            Date d = format.parse(date );
            SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");    
            String sdate=format2.format(d);        
            Timestamp fTimestamp=Timestamp.valueOf(sdate);   
            //將轉化後的時間存放到map中
            source.put("createTime", fTimestamp);
            //將map轉化為Bean
            BeanUtils.populate(esBlogVo, source);
            //將查詢出來的結果放到集合當中
            result.add(esBlogVo);
        }
        return result;
    }
    /**
     * 查詢document中最熱5個
     * @param offset
     * @param pageSize
     * @return
     * @throws ParseException 
     * @throws InvocationTargetException 
     * @throws IllegalAccessException 
     */
    public List<EsBlogVO> listHot5EsBlog (int offset,int pageSize) throws ParseException, IllegalAccessException, InvocationTargetException{
        //建立bool查詢
        MatchAllQueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();
        //設定排序
        FieldSortBuilder readSize = SortBuilders.fieldSort("readSize").order(SortOrder.DESC);
        FieldSortBuilder commentSize = SortBuilders.fieldSort("commentSize").order(SortOrder.DESC);
        FieldSortBuilder voteSize = SortBuilders.fieldSort("voteSize").order(SortOrder.DESC);
        FieldSortBuilder createTime = SortBuilders.fieldSort("createTime").order(SortOrder.DESC); 
        //查詢
       SearchResponse searchResponse = this.client.prepareSearch("myblog")
                .setTypes("blog")
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH) //設定查詢型別:1.SearchType.DFS_QUERY_THEN_FETCH 精確查詢; 2.SearchType.SCAN 掃描查詢,無序
                .setQuery(matchAllQuery)
                .addSort(readSize)
                .addSort(commentSize)
                .addSort(voteSize)
                .addSort(createTime)
                .setFrom(offset)
                .setSize(pageSize)
                .get();
        //列印語句
        System.out.println(searchResponse.toString());
        //接受結果
        List<EsBlogVO> result = new ArrayList<EsBlogVO>();
        for(SearchHit hits:searchResponse.getHits()){
            //例項化物件
            EsBlogVO esBlogVo = new EsBlogVO();
            //獲得查詢資料
            Map<String, Object> source = hits.getSource();
            //轉化時間
            String date = (java.lang.String) source.get("createTime");
            date = date.replace("Z", " UTC");//注意是空格+UTC
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");//注意格式化的表示式
            Date d = format.parse(date );
            SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");    
            String sdate=format2.format(d);        
            Timestamp fTimestamp=Timestamp.valueOf(sdate);   
            //將轉化後的時間存放到map中
            source.put("createTime", fTimestamp);
            //將map轉化為Bean
            BeanUtils.populate(esBlogVo, source);
            //將查詢出來的結果放到集合當中
            result.add(esBlogVo);
        }
        return result;
    }
    /**
     * 查詢document總記錄數
     * @return
     */
    public Integer findTotalElement() {
        //建立bool查詢
         MatchAllQueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();

        SearchRequestBuilder searchRequestBuilder = this.client.prepareSearch("myblog")
                .setTypes("blog")
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH) //設定查詢型別:1.SearchType.DFS_QUERY_THEN_FETCH 精確查詢; 2.SearchType.SCAN 掃描查詢,無序
                .setQuery(matchAllQuery);
        //執行結果
        SearchResponse response = searchRequestBuilder.get();
        long totalHits = response.getHits().totalHits;
        return new Long(totalHits).intValue();
    }
    /**
     * esBlog的document的list分頁查詢,按時間進行排序
     * @param pageable
     * @return
     * @throws ParseException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public PageBean<EsBlogVO> listEsBlogOrderByNew(PageBean<EsBlogVO> pageable) throws ParseException, IllegalAccessException, InvocationTargetException {

        //建立bool查詢
         MatchAllQueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();
        //使用should實現或者查詢
        //查詢
       SearchResponse searchResponse = this.client.prepareSearch("myblog")
                .setTypes("blog")
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH) //設定查詢型別:1.SearchType.DFS_QUERY_THEN_FETCH 精確查詢; 2.SearchType.SCAN 掃描查詢,無序
                .setQuery(matchAllQuery)
                .addSort("createTime", SortOrder.DESC)
                .setFrom(pageable.getOffSet())
                .setSize(pageable.getSize())