使用solr进行高亮显示【含angualarJS无法正常解析的解决方案】

废话不多说,直接贴代码,看完代码后,我们再解析:

代码:

/**
*通过关键词查询结果并高亮显示
*/

public class HighlightQueryDemo {

	@Autowired
	private SolrTemplate solrTemplate;

	public  Map search(Map searchMap){
		Map map = new HashMap();
		//1、查询列表
		map.putAll(searchList(searchMap));
		return map;
	}





	private Map searchWithHightlight(Map searchMap){
		Map map = new HashMap();

        //1、对高亮选项的设置
		//根据关键字查询,构建高亮显示查询对象
		HighlightQuery query = new SimpleHighlightQuery();
		
		//addField(String fieldName) 在哪一个域上高亮显示,此处设置在title高亮显示 
		HighlightOptions highlightOptions = new HighlightOptions().addField("item_title");
		//设置前缀
		highlightOptions.setSimplePrefix("<em style='color:red'>");
		//设置后缀
		highlightOptions.setSimplePostfix("</em>");
		//为查询对象设置高亮选项
		query.setHighlightoptions(highlightOptions);


        //2、对查询条件的构建
		//关键字查询 param为fieldName
		Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords")); 
                query.addCriteria(criteria);


        //3、对查询结果的获取
		//此处传入的param1:query为HighlightQuery,为Query的子接口
		HighlightPage<TbItem> page = solrTemplate.queryForHightlightPage(query,TbItem.class);

		//page.getContent()为获取原生结果,不带高亮显示,若想高亮显示,则
		//得到的是高亮入口集合
		//第一个List
		List<HighlightEntry<TbItem>> entryList = page.getHighlighted();
		for(HighlightEntry<TbItem> entry:entryList){
			//获取高亮列表
			//第二个List
			List<Highlight> highlightList = entry.getHighlights();
			/*
			for(Highlight highlight :highlightList){
				第三个List
				List<String> list = highlight.getSnipplets();
			}
			*/
			//由于我们只对一个域设置高亮,即只addField(fieldName)一次,
			//且我们未对item_title存储多值,即multiValued="false"
			//第二第三个List中都只有一个返回结果,则get(0)取第一个元素处理
			if(highlightList.size()>0 && highlightList.get(0).getSnipplets().size>0){
				//通过entry获取实例
				TbItem item = entry.getEntity();
				//替换title值为高亮显示<em style='color:red'>标题</em>
				String title = highlightList.get(0).getSnipplets().get(0);
				item.setTitle(title);
			}

		}
		 map.put("rows",page.getContent());
		 return map;
	}

}


    这个API看起来真的很繁琐,返回了3个List,让我们来捋一捋思路:


    1、第一个List:  高亮入口集合(实际在查询后,有多条返回记录,List中每个元素代表每条记录的高亮入口)

     List<HighlightEntry<TbItem>> entryList = page.getHighlighted();
    
    2、第二个List:  我们可以为多个field设置高亮,但此处我们只addField("item_title");
                   若add多个Field,则会返回多个结果,list的size取决于设置高亮域的个数
     List<Highlight> highlightList = entry.getHighlights();

    3、第三个List:  别忘了每个field都可以存储多值,贴schema.xml中的原文看看
                     multiValued="true" 多值

 

现在不出意外的话,你的title就可以高亮显示了。但如果你是用的是angularJS,页面可能显示:

<em style='color:red'>标题</em> 也就是说出现了不被解析情况,主要是angularJS采取了安全策略防止html、js等攻击。要想页面正常显示,使用$sce服务的trustAsHtml/trustAsJs采取angualarJS信任策略

1、使用过滤器filter简化开发

// 定义模块:
var app = angular.module("mall",[]);
//$sce服务写成过滤器
app.filter('trustHtml',['$sce',function($sce){
    return function(data){  //传入被过滤的内容
        return $sce.trustAsHtml(data);   //返回过滤后的内容,即信任html转换
    }
}]);

2、在页面search.html中使用过滤器

ng-bind-html指令用于显示html内容竖线 | 用于调用过滤器

    即:被过滤的内容 | 调用过滤的方法

原采用表达式输出  <em> {{item.title}} </em> 替换为:

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

猜你喜欢

转载自blog.csdn.net/itcats_cn/article/details/81879646
今日推荐