SolrJ 搜索引擎高亮显示

Dec 24, 2017 阅读(121)

标签: Solr

废话不多说,先看一下搜索引擎高亮显示效果:

搜索引擎高亮显示效果

实现代码:

	@Override
public PageInfo<JSONObject> search(String queryStr, int pageNum,int pageSize) {
	SolrQuery  params = new SolrQuery(queryStr);
	params.setHighlight(true);//开启高亮功能
	params.addHighlightField("title,description");//高亮字段,多个字段高亮字段间用逗号分隔
	params.setHighlightSimplePre("<font color='red'>");//渲染标签
	params.setHighlightSimplePost("</font>");//渲染标签 
	params.setStart((pageNum-1)*pageSize);
	params.setRows(pageSize);
	try {
		QueryResponse response = httpSolrClient.query(params);
		Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
		long numFound = response.getResults().getNumFound();
		List<JSONObject> articles = new ArrayList<JSONObject>();
		log.debug(String.format("搜索到相关结果 %s 个", numFound));
		for (SolrDocument doc : response.getResults()) {
			JSONObject article = new JSONObject();
			String id = (String) doc.getFieldValue("id");
			Map<String, List<String>> highlightingMap = highlighting.get(id);
			
			article.put("id", id);
			List<String> title = highlightingMap.get("title");
			if(null != title && title.size() > 0){
				article.put("title", title.get(0));
			}else{
				article.put("title", doc.getFieldValue("title"));
			}
			
			List<String> description = highlightingMap.get("description");
			if(null != description && description.size() > 0){
				article.put("description", description.get(0));
			}else{
				article.put("description", doc.getFieldValue("description"));
			}
			
			article.put("categoryName", doc.getFieldValue("categoryName"));
			article.put("tag", doc.getFieldValue("tag"));
			article.put("lastModifiedDate", doc.getFieldValue("lastModifiedDate"));
			
			articles.add(article);
		}
		
		Page<JSONObject> page = new Page<JSONObject>(pageNum, pageSize);
		page.setTotal(numFound);	// 总数
		page.addAll(articles);		// 结果集
		
		int navigatePages = (int) (numFound/pageSize+1);	//页码数量
		return new PageInfo<JSONObject>(page,navigatePages);
	} catch (SolrServerException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
	return null;
}

注:在开发的时候发现,明明代码要求是标题和概要都高亮处理,但实际的结果只有标题高亮显示,经过一番查找发现是概要字段在存储时没有分词处理,使用原子类型(string),将 string 改成 text_smart后就好啦,好有需要注意的是需要高亮显示的字段必须标注 stored="true"

Solr 配置文件:

...
<fieldType name="currency" class="solr.CurrencyField" precisionStep="8" defaultCurrency="USD" currencyConfig="currency.xml" />

<fieldType name="text_smart" class="solr.TextField" positionIncrementGap="100">  
<analyzer type="index">  
   <tokenizer class="solr.SmartChineseSentenceTokenizerFactory"/>  
   <filter class="solr.SmartChineseWordTokenFilterFactory"/>  
</analyzer>  
<analyzer type="query">  
   <tokenizer class="solr.SmartChineseSentenceTokenizerFactory"/>  
   <filter class="solr.SmartChineseWordTokenFilterFactory"/>  
</analyzer>  
</fieldType>


<!-- 文章:标题、类型、分类、描述、标签、创建人、创建时间、最后更新时间 -->
<field name="title" type="text_smart" indexed="true" stored="true" multiValued="false" />
<field name="type" type="string" indexed="true" stored="true" multiValued="false" />
<field name="categoryName" type="string" indexed="true" stored="true" multiValued="false" />
<field name="description" type="text_smart" indexed="true" stored="true" multiValued="false" />
<field name="content" type="text_smart" indexed="true" stored="false" multiValued="false" />
<field name="tag" type="text_smart" indexed="true" stored="true" multiValued="false" />
<!--
<field name="creator" type="string" indexed="true" stored="true" multiValued="false" />
<field name="creatorDate" type="date" indexed="true" stored="true" multiValued="false" />
<field name="lastModifier" type="date" indexed="true" stored="true" multiValued="false" />
-->

<!-- 定义 content 为默认的搜索列 -->
<defaultSearchField>content</defaultSearchField>
...