废话不多说,直接贴代码,看完代码后,我们再解析:
代码:
/**
*通过关键词查询结果并高亮显示
*/
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>