1. 程式人生 > >ElasticsearchTemplate 搜尋分頁 並高亮顯示搜尋條件

ElasticsearchTemplate 搜尋分頁 並高亮顯示搜尋條件

@Autowired
private ElasticsearchTemplate elasticsearchTemplate;

    /**
	 * 新增搜尋條件
	 * @param doc
	 * @param searchQuery
	 */
	private void withQuery(EsDoc doc,NativeSearchQueryBuilder searchQuery){
		if (!StringUtils.isEmpty(doc.getContent())) {
			BoolQueryBuilder bqb = QueryBuilders.boolQuery();
			if (StringUtils.isEmpty(doc.getSearchtype()) || doc.getSearchtype().equals("1"))
				bqb.must(QueryBuilders.matchPhraseQuery("content", doc.getContent()));
			else if (doc.getSearchtype().equals("2"))
				bqb.must(QueryBuilders.matchQuery("content", doc.getContent()));
			searchQuery.withQuery(bqb);
		}
	}
	
	/**
	 * 新增高亮條件
	 * @param searchQuery
	 */
	private void withHighlight(NativeSearchQueryBuilder searchQuery){
		Field hfield= new HighlightBuilder.Field("content")
				 .preTags("<em style='color:red'>")
				 .postTags("</em>")
				 .fragmentSize(100);
		searchQuery.withHighlightFields(hfield);
	}
	
	/**
	 * 根據搜尋結果建立esdoc物件
	 * @param smap
	 * @param hmap
	 * @return
	 */
	private EsDoc createEsDoc(Map<String, Object> smap,Map<String, HighlightField> hmap){
		EsDoc ed = new EsDoc();
		if (smap.get("title") != null)
			ed.setTitle(smap.get("title").toString());
		if (hmap.get("content") != null)
			ed.setContent(hmap.get("content").fragments()[0].toString());
		else if(smap.get("content")!=null)
			ed.setContent(smap.get("content").toString());
		if (smap.get("id") != null)
			ed.setId(smap.get("id").toString());
		return ed;
	}
	
	public Page<EsDoc> getPage(EsDoc doc, HttpServletRequest request, HttpServletResponse response){
		
		Page<EsDoc> esdocpage = new Page<EsDoc>(request, response);
		NativeSearchQueryBuilder searchQuery = new NativeSearchQueryBuilder();
		//設定索引
		searchQuery.withIndices(index);
		//設定分頁
		searchQuery.withPageable(new PageRequest(esdocpage.getPageNo() - 1, esdocpage.getPageSize()));
		//設定高亮
		withHighlight(searchQuery);
		//設定查詢條件
		withQuery(doc,searchQuery);
		
		//自定義查詢結果封裝
		AggregatedPage<EsDoc> page = elasticsearchTemplate.queryForPage(searchQuery.build(), EsDoc.class,
				new SearchResultMapper() {

					@Override
					public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz,
							Pageable pageable) {
						// TODO Auto-generated method stub
						List<T> chunk = new ArrayList<T>();

						for (SearchHit searchHit : response.getHits().getHits()) {
							Map<String, Object> smap = searchHit.getSource();
							Map<String, HighlightField> hmap = searchHit.getHighlightFields();
							chunk.add((T)createEsDoc(smap,hmap));
						}
						
						AggregatedPage<T> result=new AggregatedPageImpl<T>(chunk,pageable,response.getHits().getTotalHits());
						
						return result;
					}
				});

		esdocpage.setList(page.getContent());
		esdocpage.setCount(page.getTotalElements());
		
		return esdocpage;
	}