使用Hibernate Search方便是方便,可是找出来的结果,都是一个个的实体。而当我想要
使用高亮时,就没那么简单了。一开始走了弯路,按照以前直接用 lucene 的经验,打算自己
找到 QueryHits,然后对 QueryHits的结果进行逐个的高亮。幸好及时搜索了一下,对我帮助
最大的就是 https://forums.hibernate.org/viewtopic.php?f=9&t=982678 这篇文章。
当然,这篇文章也有点复杂了,不知道为啥要对query进行rewrite。在我看来,帮助最大的就是
提醒了我,可以用 query.setProjection(FullTextQuery.THIS, FullTextQuery.DOCUMENT_ID,FullTextQuery.DOCUMENT,FullTextQuery.SCORE,FullTextQuery.BOOST);
来获取到 Document,以及Score。有了这个之后,事情就简单多了
public List<SearchResult> search(String value) throws Exception {
Session session = getSession();
FullTextSession fullTextSession = Search.getFullTextSession( session);
StandardAnalyzer standardAnalyzer = new StandardAnalyzer( Version.LUCENE_CURRENT);
QueryParser parser = new QueryParser( Version.LUCENE_CURRENT, "ALL", standardAnalyzer);
Query query = parser.parse( value);
FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery( query);
fullTextQuery.setProjection(FullTextQuery.THIS, FullTextQuery.DOCUMENT, FullTextQuery.SCORE);
Collection<Object[]> queryResult = fullTextQuery.list();
QueryScorer qs = new QueryScorer( query);
Formatter formatter = new SimpleHTMLFormatter( "<b><font color=\"red\">", "</font></b>");
Highlighter highlighter = new Highlighter( formatter, qs);
List<SearchResult> result = new ArrayList<SearchResult>();
for ( Object[] objs: queryResult ) {
Document document = (Document) objs[1];
org.apache.lucene.document.Field field = document.getField("ALL");
String[] highlight = highlighter.getBestFragments( standardAnalyzer, "ALL", field.stringValue(), 5);
// 这儿就是处理如何返回结果了
}
return result;
}
当然,前提是你的这些内容要是Store.YES才行。