-
第一種方式是solrj操作:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
public SolrDocumentList query(String str) { SolrQuery query = new SolrQuery(str); query.setHighlight( true ); //開啓高亮功能 query.addHighlightField( "name,content" ); //高亮字段 :多個域可以用空格或者逗號分隔 query.setHighlightSimplePre( "<font color=red >" ); //渲染標籤 query.setHighlightSimplePost( "</font>" ); //渲染標籤 query.setParam( "f.content.hl.fragsize" , "200" ); QueryResponse qr=server.query(query); //執行查詢 SolrDocumentList dlist=qr.getResults(); System.out.println( "總數:" +dlist.getNumFound()); //第一個Map的鍵是文檔的ID,第二個Map的鍵是高亮顯示的字段名 Map<String, Map<String, List<String>>> map = qr.getHighlighting(); for ( int i= 0 ;i<dlist.size();i++){ SolrDocument d=dlist.get(i); //獲取每一個document Map<String, String> mapRe = new HashMap<String, String>(); mapRe.put( "id" , d.get( "id" ).toString()); if (map.get(d.get( "id" )).get( "name" ) == null ){ mapRe.put( "name" , d.getFieldValue( "name" ).toString()+ "--" +d.getFieldValue( "author" ).toString()+ "-" +d.getFieldValue( "theme" )); } else { mapRe.put( "name" , map.get(d.get( "id" )).get( "name" ).toString()+ "--" +d.getFieldValue( "author" ).toString()+ "-" +d.getFieldValue( "theme" )); } if (map.get(d.get( "id" )).get( "content" ) == null ){ mapRe.put( "content" , d.getFieldValue( "content" ).toString().substring( 0 , 200 )); } else { mapRe.put( "content" , map.get(d.get( "id" )).get( "content" ).toString()); } list.add(mapRe); } return list; } |
2 ) 另外的方法,配置solrconfig.xml
solr是在lucene的基礎上做的開發,那麼在某些功能的實現上,與lucene也會有相似之處。
solr的高亮顯示(包括自動摘要),是通過hl這個param,以及其相關變量來實現的,hl是hightlight的簡寫。lucene中是通過highlighter來操作高亮和摘要的。
配置高亮的相關屬性,是在solrconfig.xml中配置的。在 <requestHandler name="search" class="solr.SearchHandler" default="true">下進行配置。solrconfig.xml文件中包含多個requestHandler的標籤,但是只有在上述的名爲search的標籤中配置纔有效。現將配置的案列公佈如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
< requestHandler name = "search" class = "solr.SearchHandler" default = "true" > <!-- default values for query parameters can be specified, these will be overridden by parameters in the request --> < lst name = "defaults" > < str name = "echoParams" >explicit</ str > < int name = "rows" >10</ int > < str name = "df" >text</ str > < str name = "hl" >true</ str > < str name = "hl.fl" >content</ str > < str name = "f.name.hl.fragsize" >50</ str > < str name = "hl.simple.pre" ><font color="red></ str > < str name = "hl.simple.post" ></font></ str > </ lst > </ requestHandler > |
其中,hl是指定是否使用高亮;hl.fl,指定對哪些域進行高亮,對多個域進行高亮的話,好像是用逗號隔開;f.name.hl.fragsize是指摘要的長度,默認0代表不做摘要。而hl.simple.pre和hl.simple.post則是指定高亮時顯示的格式,默認是<em></em>。詳細內容請參見:http://wiki.apache.org/solr/HighlightingParameters。設置完成後,
在solrj中,通過QueryResponse對象的getHighlighting()方法獲得。該方法返回 Map<String,Map<String,List<String>>>類型的數據。其中第一個Map中的key是id,第二個Map中的key是field,List<String>中封裝的就是高亮與摘要處理過後的內容了
Map<String, Map<String, List<String>>> map = response.getHighlighting();
通過這個api的方法就可以得到高亮的內容,高亮的內容通過 key 跟索引的document部分關聯起來
這個key就是document 的id
參數詳細說明:
1.hl.fl: 用空格或逗號隔開的字段列表。要啓用某個字段的highlight功能,就得保證該字段在schema中是stored。如果該參數未被給出,那麼就會高亮默認字段
standard handler會用df參數,dismax字段用qf參數。你可以使用星號去方便的高亮所有字段。如果你使用了通配符,那麼要考慮啓用hl.requiredFieldMatch選項。
2.hl.requireFieldMatch:
如果置爲true,除非該字段的查詢結果不爲空纔會被高亮。它的默認值是false,意味着它可能匹配某個字段卻高亮一個不同的字段。如果hl.fl使用了通配符,那麼就要啓用該參數。儘管如此,如果你的查詢是all字段(可能是使用copy-field
指令),那麼還是把它設爲false,這樣搜索結果能表明哪個字段的查詢文本未被找到
3.hl.usePhraseHighlighter:
如果一個查詢中含有短語(引號框起來的)那麼會保證一定要完全匹配短語的纔會被高亮。
4.hl.highlightMultiTerm
如果使用通配符和模糊搜索,那麼會確保與通配符匹配的term會高亮。默認爲false,同時hl.usePhraseHighlighter要爲true。
5.hl.snippets:
這是highlighted片段的最大數。默認值爲1,也幾乎不會修改。如果某個特定的字段的該值被置爲0(如f.allText.hl.snippets=0),這就表明該字段被禁用高亮了。你可能在hl.fl=*時會這麼用。
6.hl.fragsize:
每個snippet返回的最大字符數。默認是100.如果爲0,那麼該字段不會被fragmented且整個字段的值會被返回。大字段時不會這麼做。
7.hl.mergeContiguous:
如果被置爲true,當snippet重疊時會merge起來。
8.hl.maxAnalyzedChars:
會搜索高亮的最大字符,默認值爲51200,如果你想禁用,設爲-1
9.hl.alternateField:
如果沒有生成snippet(沒有terms 匹配),那麼使用另一個字段值作爲返回。
10.hl.maxAlternateFieldLength:
如果hl.alternateField啓用,則有時需要制定alternateField的最大字符長度,默認0是即沒有限制。所以合理的值是應該爲:hl.snippets
* hl.fragsize這樣返回結果的大小就能保持一致。
11.hl.formatter:一個提供可替換的formatting算法的擴展點。默認值是simple,這是目前僅有的選項。顯然這不夠用,你可以看看org.apache.solr.highlight.HtmlFormatter.java
和 solrconfig.xml中highlighting元素是如何配置的。
注意在不論原文中被高亮了什麼值的情況下,如預先已存在的em tags,也不會被轉義,所以在有時會導致假的高亮。
12.hl.fragmenter:
這個是solr制定fragment算法的擴展點。gap是默認值。regex是另一種選項,這種選項指明highlight的邊界由一個正則表達式確定。這是一種非典型的高級選項。爲了知道默認設置和fragmenters
(and formatters)是如何配置的,可以看看solrconfig.xml中的highlight段。
regex 的fragmenter有如下選項:
13.hl.regex.pattern:正則表達式的pattern
14.hl.regex.slop:這是hl.fragsize能變化以適應正則表達式的因子。默認值是0.6,意思是如果hl.fragsize=100那麼fragment的大小會從40-160.
以下是自己項目的代碼實現:
query.setHighlight(true);//開啓高亮
query.setParam("hl.fl", "tags");//高亮字段
query.setHighlightSimplePre("<font color=\"red\" >");//渲染標籤
query.setHighlightSimplePost("</font>");
query.setParam("f.content.hl.fragsize", "1000");
Iterator<SolrDocument> it = solrDocumentList.iterator();
SolrDocument doc = null;
RecommendVo vo = null;
Map<String, Map<String, List<String>>> map = response.getHighlighting();
while (it.hasNext())
{
doc = it.next();
if(map.get(doc.get("productId"))!=null)
{
doc.setField("tags", map.get(doc.get("productId").toString()).get("tags").toString());
}
vo = perdocToRecommendVo(doc);
vos.add(vo);
}
參考文獻:
http://my.oschina.net/MrMichael/blog/226012?fromerr=g8ngbvZx