废话不多说,先看一下搜索引擎高亮显示效果:
实现代码:
@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> ...