我们使用搜索引擎(如谷歌,百度)都会在检索结果页高亮显示检索词.这种高亮显示很醒目,能够让我们迅速的关注到我们需要的信息上.
Lucene 的contrib已经包含了这样的功能模块
在检索结果中实现高亮的代码:
public void testHits() throws Exception { IndexSearcher searcher = new IndexSearcher(TestUtil.getBookIndexDirectory()); TermQuery query = new TermQuery(new Term("title", "action")); TopDocs hits = searcher.search(query, 10); QueryScorer scorer = new QueryScorer(query, "title"); Highlighter highlighter = new Highlighter(scorer); highlighter.setTextFragmenter( new SimpleSpanFragmenter(scorer)); Analyzer analyzer = new SimpleAnalyzer(); for (int i = 0; i < hits.scoreDocs.length; i++) { Document doc = searcher.doc(hits.scoreDocs[i].doc); String title = doc.get("title"); TokenStream stream = TokenSources.getAnyTokenStream(searcher.getIndexReader(), hits.scoreDocs[i].doc, "title", doc, analyzer); String fragment = highlighter.getBestFragment(stream, title); System.out.println(fragment); } } //输出 //JUnit in <B>Action</B> //Lucene in <B>Action</B> //Tapestry in <B>Action</B>
顾名思义,FastVectorHighlighter是一个快速的高亮工具,相对于Highlighter它有三个好处:
1.FastVectorHighlighter can support fields that are tokenized by n-gram tokenizers. Highlighter cannot support such fields very well.
2.FastVectorHighlighter 可以输出不同颜色的高亮.
3.FastVectorHighlighter 可以对词组高亮.(如检索lazy dog,FastVectorHighlighter<b>lazy dog</b>,而Highlighter则是<b>dog</b>)
FastVectorHighlighter代码:
public class FastVectorHighlighterSample { static final String[] DOCS = { // #A "the quick brown fox jumps over the lazy dog", // #A "the quick gold fox jumped over the lazy black dog", // #A "the quick fox jumps over the black dog", // #A "the red fox jumped over the lazy dark gray dog" // #A }; static final String QUERY = "quick OR fox OR \"lazy dog\"~1"; // #B static final String F = "f"; static Directory dir = new RAMDirectory(); static Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT); public static void main(String[] args) throws Exception { if (args.length != 1) { System.err.println("Usage: FastVectorHighlighterSample <filename>"); System.exit(-1); } makeIndex(); // #C searchIndex(args[0]); // #D } static void makeIndex() throws IOException { IndexWriter writer = new IndexWriter(dir, analyzer, true, MaxFieldLength.LIMITED); for(String d : DOCS){ Document doc = new Document(); doc.add(new Field(F, d, Store.YES, Index.ANALYZED, TermVector.WITH_POSITIONS_OFFSETS)); writer.addDocument(doc); } writer.close(); } static void searchIndex(String filename) throws Exception { QueryParser parser = new QueryParser(Version.LUCENE_CURRENT, F, analyzer); Query query = parser.parse(QUERY); FastVectorHighlighter highlighter = getHighlighter(); // #F FieldQuery fieldQuery = highlighter.getFieldQuery(query); // #G IndexSearcher searcher = new IndexSearcher(dir); TopDocs docs = searcher.search(query, 10); FileWriter writer = new FileWriter(filename); writer.write("<html>"); writer.write("<body>"); writer.write("<p>QUERY : " + QUERY + "</p>"); for(ScoreDoc scoreDoc : docs.scoreDocs) { String snippet = highlighter.getBestFragment( // #H fieldQuery, searcher.getIndexReader(), // #H scoreDoc.doc, F, 100 ); // #H if (snippet != null) { // #I writer.write(scoreDoc.doc + " : " + snippet + "<br/>"); // #I } } writer.write("</body></html>"); writer.close(); searcher.close(); } static FastVectorHighlighter getHighlighter() { FragListBuilder fragListBuilder = new SimpleFragListBuilder(); // #J FragmentsBuilder fragmentBuilder = // #K new ScoreOrderFragmentsBuilder( // #K BaseFragmentsBuilder.COLORED_PRE_TAGS, // #K BaseFragmentsBuilder.COLORED_POST_TAGS); // #K return new FastVectorHighlighter(true, true, // #L fragListBuilder, fragmentBuilder); // #L } } #A 示例文档 #B 示例查询语句 #C 创建索引 #D 检索并打印结果 #E Store.YES 并且 TermVector.WITH_POSITIONS_OFFSETS #F 获得一个 FastVectorHighlighter实例 #G 创建FieldQuery #H 高亮片断 #I 打印高亮后片断 #J 创建 SimpleFragListBuilder #K 创建多颜色标签 ScoreOrderFragmentsBuilder #L 创建 FastVectorHighlighter 实例
LUCENE.NET QQ交流群(81361051)