Lucene入门级笔记三 -- 给关键词添加高亮效果

EffortsRun 2011-10-24

1. 使用高亮器。

 

2. 高亮原理?

   例如,你要关键字红色?其实就是在匹配出的关键字加上一个前缀后缀。

   例如<font color="red">全文检索</font>

 

3. 如何构建高亮器?

/*
    * 在这之前实际上要检索结果 Document 对象已经构建出来了。也就是说检索已经出来结果了。	
    * 但是出来的结果并没有加上高亮效果,也就是前缀后缀还没有加上去。
    * 于是 Highlighter 要在查询出的结果数据再一次分词,然后检索关键字,再给关键字前后附上指定的前缀后缀
    *		 -- 这些信息在构建 Highlighter 时必须提供
    * getBestFragment 方法返回其内部加完高亮后的文本。然后程序员手动替换掉 Docoument 中原来的值。
    * 我在想能不能弄一个 HighlightFormater 出来,接收一个 Document 参数,高亮后再返回出来不省事么?
    * 或者提供一个重装后支持高亮的 Document 对象。
    */
   String text = highlighter.getBestFragment(analyzer, "content", doc.get("content"));
   if (text != null) {
        doc.getField("content").setValue(text); // 使用高亮后的文本替换原始内容
   }

 

4. 使用高亮器进行高亮操作

   这个 API 设计得觉得不怎么好,比较绕。暴露出来了一些程序员比较容易犯错的东西。

/*
    * 在这之前实际上要检索结果 Document 对象已经构建出来了。也就是说检索已经出来结果了。	
    * 但是出来的结果并没有加上高亮效果,也就是前缀后缀还没有加上去。
    * 于是 Highlighter 要在查询出的结果数据再一次分词,然后检索关键字,再给关键字前后附上指定的前缀后缀
    *		 -- 这些信息在构建 Highlighter 时必须提供
    * getBestFragment 方法返回其内部加完高亮后的文本。然后程序员手动替换掉 Docoument 中原来的值。
    * 我在想能不能弄一个 HighlightFormater 出来,接收一个 Document 参数,高亮后再返回出来不省事么?
    * 或者提供一个重装后支持高亮的 Document 对象。
    */
   String text = highlighter.getBestFragment(analyzer, "content", doc.get("content"));
   if (text != null) {
        doc.getField("content").setValue(text); // 使用高亮后的文本替换原始内容
   }

 

5 测试代码

public class HighlighterTest {
	/* IKAnalyzer 是一个支持Lucene3.0 API 的中文分词器 */
	private static Analyzer analyzer = new IKAnalyzer();
	/**
	 * 搜索的数据是使用的 ArticleIndexDaoTest 中的保存操作的数据。
	 * 因此,代码中出现的 "content" 实际上是保存的时候,给 Document 添加的一个 Field
	 * 保存代码在《Lucene-索引库的CRUD API 演示》中有
	 */
	@Test
	public void test() throws Exception {
		// 搜索条件
		String queryString = "lucene";
		// =================================================================
		// a, 把搜索字符串转为Query对象
		QueryParser queryParser = new QueryParser(Version.LUCENE_30, "content", analyzer);
		Query query = queryParser.parse(queryString);
		// b, 搜索,得到中间结果
		IndexSearcher indexSearcher = new IndexSearcher(Configuration.getDirectory());
		TopDocs topDocs = indexSearcher.search(query, 100); // 返回前100条结果
		ScoreDoc[] scoreDocs = topDocs.scoreDocs; // 前n条记录的信息
		// --------------------------------------------
		// 一、创建并配置高亮器
		Formatter formater = new SimpleHTMLFormatter("<font color='red'>", "</font>"); // 高亮效果,默认为<B>与</B>
		Scorer scorer = new QueryScorer(query); // 查询条件
		Highlighter highlighter = new Highlighter(formater, scorer);
		highlighter.setTextFragmenter(new SimpleFragmenter(20)); // 摘要的大小,默认为100个字符
		// --------------------------------------------
		// c, 处理结果
		List<Article> list = new ArrayList<Article>();
		for (int i = 0; i < scoreDocs.length; i++) {
			ScoreDoc scoreDoc = scoreDocs[i]; // 1,获得一个文档的信息
			Document doc = indexSearcher.doc(scoreDoc.doc); // 2,根据文档编号取出相应的Document
			// --------------------------------------------
			// 二、使用高亮器进行高亮操作
			// 返回高亮后的(关键词出现次数最多的地方的)一段文本,如果当前高亮的属性中没有出搜索的关键词,则返回null
			String text = highlighter.getBestFragment(analyzer, "content", doc.get("content"));
			if (text != null) {
				doc.getField("content").setValue(text); // 使用高亮后的文本替换原始内容
			}
			// --------------------------------------------
			list.add(ArticleDocumentUtils.document2Article(doc));// 3,把Document转为Article
		}
		// =================================================================
		// 显示结果
		for (Article article : list) {
			System.out.println("-------> id = " + article.getId());
			System.out.println("title   = " + article.getTitle());
			System.out.println("content = " + article.getContent());
		}
	}
}

 

相关推荐