Springboot+AngularJS+Spring-data-Solr:搜索内容匹配高亮显示

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_26975307/article/details/84339676

Java后台部分:

package com.phubing.search.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.HighlightOptions;
import org.springframework.data.solr.core.query.HighlightQuery;
import org.springframework.data.solr.core.query.Query;
import org.springframework.data.solr.core.query.SimpleHighlightQuery;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.data.solr.core.query.result.HighlightEntry;
import org.springframework.data.solr.core.query.result.HighlightEntry.Highlight;
import org.springframework.data.solr.core.query.result.HighlightPage;
import org.springframework.data.solr.core.query.result.ScoredPage;

import com.alibaba.dubbo.config.annotation.Service;
import com.phubing.pojo.TbItem;
import com.phubing.search.service.ItemSearchService;

/**
 * 如果搜索时间过长,会造成搜索超时
 * dubbo搜索时间默认为1秒钟
 * 并发高或者服务器性能不够
 * 可以加上@Service(timeout=3000)注解,设置dubbo超时时间
 * 如果服务方和消费方同时设置了超时时间,dubbo会以消费方的设置为准
 * 
 * @author phubing
 *
 */
@Service(timeout=3000)
public class ItemSearchServiceImpl implements ItemSearchService{
	@Autowired
	private SolrTemplate solrTemplate;
	
	@Override
	public Map<String, Object> search(Map searchMap) {
		Map<String, Object> map = new HashMap<String, Object>();
		
		/*Query query = new SimpleQuery("*:*");
		//is表示匹配
		*//**
		 * {
		 * "keywords":"关键字"
		 * }
		 *//*
		Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords"));
		query.addCriteria(criteria );
		ScoredPage<TbItem> page = solrTemplate.queryForPage(query, TbItem.class);
		//将当前返回结果返回给rows
		*//**
		 * 返回的格式为
		 * {rows:[]}
		 * 
		 *//*
		map.put("rows", page.getContent());*/
		
		HighlightQuery query = new SimpleHighlightQuery();
		HighlightOptions highlightOptions = new HighlightOptions().addField("item_title");
		//前缀
		highlightOptions.setSimplePrefix("<strong style=\'color:red;\'>");
		//后缀
		highlightOptions.setSimplePostfix("</strong>");
		
		//为查询对象设置高亮选项
		/**
		 * <strong style="color:red;">搜索关键字/词</strong>
		 */
		query.setHighlightOptions(highlightOptions);
		
		//关键字查询
		Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords"));
		query.addCriteria(criteria );
		//返回一个高亮页对象
		HighlightPage<TbItem> page = solrTemplate.queryForHighlightPage(query, TbItem.class);
		/**
		 * 1、此时可以获取到一个不经过高亮处理的内容 page.getContent()
		 * 2、需要从高亮入口集合获取
		 * 3、entryList集合的每个对象,就是每条记录的内容
		 * 4、HighlightEntry<TbItem>是高亮入口对象,存在一个获取所有高亮的方法
		 * 5、高亮列表中为何还有一个高亮列表?
		 * 	5.1 HighlightOptions().addField设置高亮列,并且可以建立多个高亮列
		 * 	5.2 建立了多个高亮列就会返回多个高亮列
		 * 6、为何Highlight highlightEntry也是一个高亮列,而不是直接获取一个高亮值?
		 * 	6.1 每一个域有可能存储多值,在schema.xml中配置了N个单独的field,所以每一个高亮列都有其单独的域
		 * 7、如何让页面产生高亮结果?
		 * 	7.1 从高亮列表中获取高亮列,highlightsList.get(0).getSnipplets().get(0)
		 * 	7.2 将高亮页赋予结果集page.getContent():item.setTitle(highlightsList.get(0).getSnipplets().get(0));
		 * 
		 */
		//需要从返回高亮对象中获取高亮结果再返回,即在高亮入口集合中遍历
		List<HighlightEntry<TbItem>> entryList = page.getHighlighted();
		for (HighlightEntry<TbItem> entry : entryList) {
			//得到一个高亮列表
			List<Highlight> highlightsList = entry.getHighlights();
			//是否还需要遍历取决于高亮列的个数
			/*for (Highlight highlightEntry : highlightsList) {
				List<String> snippletsList = highlightEntry.getSnipplets();
			}*/
			if(highlightsList.size() > 0 && highlightsList.get(0).getSnipplets().size() > 0) {
				//与page.getContent()是同一个
				TbItem item = entry.getEntity();
				//确定只有一列的情况下
				item.setTitle(highlightsList.get(0).getSnipplets().get(0));
			}
			
		}
		map.put("rows", page.getContent());
		
		return map;
	}
	

}

AngularJS中controller层:

/*
Angularjs为了防止(html、js)攻击,会将后端返回的html代码原样输出,此时需要采用$sce,即Angularjs信任策略,使用后就会解析后再输出
trustHtml、trustJs
将过滤服务封装成通用过滤器
*/
//封装通用过滤器
app.filter('trustHtml',['$sce', function($sce){
	//传入的参数就是需要过滤的内容
	return function(data){
		return $sce.trustAsHtml(data);
	}
}]);

页面调用:

<div class="attr" ng-bind-html="item.title | trustHtml"></div>

猜你喜欢

转载自blog.csdn.net/qq_26975307/article/details/84339676