`

Lucene+HighLighter高亮显示实例

    博客分类:
  • Java
阅读更多

今天搞了一个关于Lucene的例子,权当入门教程。网上有很多资料,但是要么不全、要么不好用,所以这里把全部代码以及依赖的包贴上来了。

 

功能包括:创建索引、检索索引、高亮显示查询结果。分词使用的庖丁解牛。

 

使用前先下载相关的LuceneCore jar包、LuceneHighLighter jar包、庖丁解牛分分词jar包、庖丁解牛词典。并设定环境变量PAODING_DIC_HOME指向词典位置。

前两个可以到官方网站找,庖丁去http://code.google.com/p/paoding/downloads/list下载。

 

Lucene庖丁整合方式1:

1、将paoding-analysis.jar拷贝到项目的WEB-INF/lib目录;
2、接着需要设置环境变量PAODING_DIC_HOME,变量名:PAODING_DIC_HOME 变量值:E:\paoding\dic
3、第三步将E:\paoding\src目录下的paoding-dic-home.properties属性文件拷贝到项目的src目录下,添加2行

paoding.dic.home.config-fisrt=this
paoding.dic.home=E:/paoding/dic

Lucene庖丁整合方式2:

修改E:\paoding\src\paoding-dic-home.properties,增加一行

paoding.dic.home=classpath:dic

然后运行ant重新生成一个庖丁jar,拷贝到lib下就OK了。

第一种方式便于更新字典,第二种便于移植。本例使用第二种方法整合。

关于庖丁环境的设置可以参考net\paoding\analysis\Constants.java。

 

 

使用时注意LuceneCore和LuceneHighLighter的版本配置。我开始使用lucene-core-2.3.2.jar+Highlighter 2.4,后台报错,明显的版本问题。现在使用的是Lucene 2.3.2 + Highlighter 2.2.0。

 

主要代码实现:

CreateIndex:创建索引文件

package demo;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;

import net.paoding.analysis.analyzer.PaodingAnalyzer;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;


/**
 * 建立索引
 * 
 */
public class CreateIndex {
	
	public void createIndex() throws Exception {
		/* 指明要索引文件夹的位置,这里是C盘的S文件夹下 */
		File surceFileDir = new File("D:\\save\\source");

		/* 这里放索引文件的位置 */
		File indexFileDir = new File("D:\\save");
		
		//Analyzer luceneAnalyzer = new StandardAnalyzer();
		Analyzer luceneAnalyzer = new PaodingAnalyzer();//使用庖丁解牛分词法
		
		IndexWriter indexWriter = new IndexWriter(indexFileDir, luceneAnalyzer, true);///参数isEmpty是false表示增量索引
		File[] sourceFextFiles = surceFileDir.listFiles();
		long startTime = new Date().getTime();

		// 增加document到索引去
		for (int i = 0; i < sourceFextFiles.length; i++) {
			if (sourceFextFiles[i].isFile()
					&& sourceFextFiles[i].getName().endsWith(".txt")) {
				System.out.println("File " + sourceFextFiles[i].getCanonicalPath() + "正在被索引....");
				String temp = FileReaderAll(sourceFextFiles[i].getCanonicalPath(), "GBK");
				System.out.println(temp);
				Document document = new Document();
				Field FieldPath = new Field("path", sourceFextFiles[i].getPath(), Field.Store.YES, Field.Index.NO);
				Field FieldBody = new Field("body", temp, Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.WITH_POSITIONS_OFFSETS);
				Field FieldTitle = new Field("title", temp, Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.WITH_POSITIONS_OFFSETS);
				document.add(FieldPath);
				document.add(FieldBody);document.add(FieldTitle);
				indexWriter.addDocument(document);
			}
		}
		// optimize()方法是对索引进行优化
		indexWriter.optimize();
		indexWriter.close();

		// 测试一下索引的时间
		long endTime = new Date().getTime();
		System.out.println("这花费了" + (endTime - startTime) + " 毫秒来把文档增加到索引里面去!"
				+ indexFileDir.getPath());
	}

	public static String FileReaderAll(String FileName, String charset)
			throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				new FileInputStream(FileName), charset));
		String line = new String();
		String temp = new String();

		while ((line = reader.readLine()) != null) {
			temp += line;
		}
		reader.close();
		return temp;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			new CreateIndex().createIndex();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}
 

 

QueryHighLighter:检索关键字并高亮显示

package demo;

import java.io.StringReader;

import net.paoding.analysis.analyzer.PaodingAnalyzer;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Document;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocCollector;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;

import test.TestLuceneHighlighter2;


/**
 * 高亮显示检索结果
 * Lucene 2.3.2 + Highlighter 2.2.0 的分页+高亮显示代码例子.<br>
 * Lucene和Highlighter不是最新版本可以升级。
 */
public class QueryHighLighter {

	private static final String FIELD_TITLE = "title";

	private static final String FIELD_BODY = "body";

	public synchronized Analyzer getAnalyzer() {
		return new PaodingAnalyzer();// 此处使用"庖丁解牛"分词法,另外一种是中科院分词法
	}

	public String test(String queryString, int begin, int number) {
		StringBuffer sb = new StringBuffer();
		IndexSearcher isearcher = null;
		try {
			isearcher = new IndexSearcher("D:\\save");
			/* 下面这个表示要同时搜索这两个域,而且只要一个域里面有满足我们搜索的内容就行 */
			BooleanClause.Occur[] clauses = { BooleanClause.Occur.SHOULD,
					BooleanClause.Occur.SHOULD };
			TopDocCollector collector = new TopDocCollector(10);
			/*Query query = MultiFieldQueryParser.parse(queryString,
					new String[] { FIELD_TITLE, FIELD_BODY }, clauses,
					getAnalyzer());*/
			QueryParser queryParse = new QueryParser(FIELD_TITLE, getAnalyzer());   
			Query query = queryParse.parse(queryString);  
			
			isearcher.search(query, collector);
			ScoreDoc[] hits = collector.topDocs().scoreDocs;
			// 用这个进行高亮显示,默认是<b>..</b>
			// 用这个指定<read>..</read>
			SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<b><font color='red'>", "</font></b>");
			// 构造高亮
			// 指定高亮的格式
			// 指定查询评分
			Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));
			// 这个一般等于你要返回的,高亮的数据长度
			// 如果太小,则只有数据的开始部分被解析并高亮,且返回的数据也少
			// 太大,有时太浪费了。
			highlighter.setTextFragmenter(new SimpleFragmenter(Integer.MAX_VALUE));
			for (int i = begin; i < hits.length && i < begin + number; i++) {
				Document doc = isearcher.doc(hits[i].doc);
				String value = doc.get(FIELD_TITLE);
				String value2 = doc.get(FIELD_BODY);
				// 有三个参数
				// 分析器
				// 要解析的字段名
				// 要解析的数据
				//System.out.println(highlighter.getBestFragment(getAnalyzer(),
				//		FIELD_TITLE, doc.get(FIELD_TITLE)));
				
				if (value != null) {
					TokenStream tokenStream = getAnalyzer().tokenStream(FIELD_TITLE, new StringReader(value));
					String str = highlighter.getBestFragment(tokenStream, value);
					sb.append("<li><li>").append(str).append("<br/>");
					System.out.println(str);
				} 
				
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (isearcher != null) {
				try {
					isearcher.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return sb.toString();
	}
	
	public static void main(String[] args){
		TestLuceneHighlighter2 t = new TestLuceneHighlighter2();
		String queryString = "中华人民共和国";
		int begin = 0;
		int number = 10;
		t.test(queryString, begin, number);
	}

}
 

 

附加上传net\paoding\analysis\Constants.java便于理解参数设置:

package net.paoding.analysis;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 
 * @author Zhiliang Wang [qieqie.wang@gmail.com]
 * 
 * @since 2.0.0
 */
public class Constants {

	/**
	 * "词典目录安装目录"配置的优先级别
	 * <p>
	 * "system-env"以及其他非"this"的配置,表示优先从环境变量PAODING_DIC_HOME的值找词典目录安装环境
	 * "this"表示优先从本配置文件的paoding.dic.home配置项找<br>
	 * 只有在高优先级没有配置,才会找低优先级的配置。 默认环境变量的优先级别高于paoding-analysis.properties属性文件配置。
	 */
	public static final String DIC_HOME_CONFIG_FIRST = "paoding.dic.home.config-first";
	public static final String DIC_HOME_CONFIG_FIRST_DEFAULT = "system-env";

	/**
	 * 词典安装目录环境变量名
	 */
	public static final String ENV_PAODING_DIC_HOME = "PAODING_DIC_HOME";

	// -------------------------------------------------------------
	/**
	 * 词典安装目录
	 * <p>
	 * 默认值为null,以在环境变量和配置文件都没有配置paoding.dic.home的情况下,让PaodingMaker尝试从当前工作目录下、类路径下探索是否存在dic目录
	 */
	public static final String DIC_HOME = "paoding.dic.home";
	public static final String DIC_HOME_DEFAULT = null;

	// -------------------------------------------------------------
	//
	public static final String DIC_CHARSET = "paoding.dic.charset";
	public static final String DIC_CHARSET_DEFAULT = "UTF-8";

	// -------------------------------------------------------------
	// dictionaries which are skip
	public static final String DIC_SKIP_PREFIX = "paoding.dic.skip.prefix";
	public static final String DIC_SKIP_PREFIX_DEFAULT = "x-";

	// -------------------------------------------------------------
	// chinese/cjk charactors that will not token
	public static final String DIC_NOISE_CHARACTOR = "paoding.dic.noise-charactor";
	public static final String DIC_NOISE_CHARACTOR_DEFAULT = "x-noise-charactor";

	// -------------------------------------------------------------
	// chinese/cjk words that will not token
	public static final String DIC_NOISE_WORD = "paoding.dic.noise-word";
	public static final String DIC_NOISE_WORD_DEFAULT = "x-noise-word";

	// -------------------------------------------------------------
	// unit words, like "ge", "zhi", ...
	public static final String DIC_UNIT = "paoding.dic.unit";
	public static final String DIC_UNIT_DEFAULT = "x-unit";

	// -------------------------------------------------------------
	// like "Wang", "Zhang", ...
	public static final String DIC_CONFUCIAN_FAMILY_NAME = "paoding.dic.confucian-family-name";
	public static final String DIC_CONFUCIAN_FAMILY_NAME_DEFAULT = "x-confucian-family-name";
	
	// -------------------------------------------------------------
	// like 
	public static final String DIC_FOR_COMBINATORICS = "paoding.dic.for-combinatorics";
	public static final String DIC_FOR_COMBINATORICS_DEFAULT = "x-for-combinatorics";

	// -------------------------------------------------------------
	// like 
	public static final String DIC_DETECTOR_INTERVAL = "paoding.dic.detector.interval";
	public static final String DIC_DETECTOR_INTERVAL_DEFAULT = "60";

	// -------------------------------------------------------------
	// like "default", "max", ...
	public static final String ANALYZER_MODE = "paoding.analyzer.mode";
	public static final String ANALYZER_MOE_DEFAULT = "most-words";

	// -------------------------------------------------------------
	// 
	public static final String ANALYZER_DICTIONARIES_COMPILER = "paoding.analyzer.dictionaries.compiler";
	public static final String ANALYZER_DICTIONARIES_COMPILER_DEFAULT = null;

	// -------------------------------------------------------------
	private static final Map/* <String, String> */map = new HashMap();

	static {
		map.put(DIC_HOME_CONFIG_FIRST, DIC_HOME_CONFIG_FIRST_DEFAULT);
		map.put(DIC_HOME, DIC_HOME_DEFAULT);
		map.put(DIC_CHARSET, DIC_CHARSET_DEFAULT);
		map.put(DIC_SKIP_PREFIX, DIC_SKIP_PREFIX_DEFAULT);
		map.put(DIC_NOISE_CHARACTOR, DIC_NOISE_CHARACTOR_DEFAULT);
		map.put(DIC_NOISE_WORD, DIC_NOISE_WORD_DEFAULT);
		map.put(DIC_UNIT, DIC_UNIT_DEFAULT);
		map.put(DIC_CONFUCIAN_FAMILY_NAME, DIC_CONFUCIAN_FAMILY_NAME_DEFAULT);
		map.put(DIC_FOR_COMBINATORICS, DIC_FOR_COMBINATORICS_DEFAULT);
		map.put(DIC_DETECTOR_INTERVAL, DIC_DETECTOR_INTERVAL_DEFAULT);
		map.put(ANALYZER_MODE, ANALYZER_MOE_DEFAULT);
		map.put(ANALYZER_DICTIONARIES_COMPILER, ANALYZER_DICTIONARIES_COMPILER_DEFAULT);
	}

	//
	public static final String KNIFE_CLASS = "paoding.knife.class.";

	public static String getProperty(Properties p, String name) {
		return p.getProperty(name, (String) map.get(name));
	}
}
 

 

 

 

 

 

 

 

分享到:
评论
1 楼 zbmartin 2010-07-01  
恩,很好。很详细,特别是jar包还把版本号写出来,看来lz很细心,这也给大家学习带来了很大的方便

相关推荐

    lucene 多字段查询+文字高亮显示

    首先,需要创建一个Highlighter实例,然后提供查询解析器、文档和字段的Analyzer,以及高亮样式。Highlighter会分析文本,找到匹配的片段,并返回已标记的HTML字符串。 在实际应用中,你可能需要结合这两者,即根据...

    lucene-highlighter-3.4.0.jar

    其中,Lucene Highlighter是其重要的组成部分,专门用于在搜索结果中对匹配关键词进行高亮显示,极大地提升了用户在海量数据中查找相关信息的效率。本文将详细介绍Lucene Highlighter 3.4.0版本的相关知识点。 一、...

    lucene-highlighter-4.4.0.jar

    首先,Highlighter模块的核心任务是高亮显示搜索匹配的部分。在搜索过程中,用户可能输入了多个关键词或短语,Highlighter会找出这些关键词在文档中的出现位置,并通过特定的标记(如加粗、斜体或颜色变化)来突出...

    一步一步跟我学习lucene(11)---lucene搜索之高亮显示highlighter

    Lucene提供了Highlighter组件来实现搜索结果的高亮显示。Highlighter根据查询和文档内容生成高亮的片段。这个组件支持多种策略,例如基于TF-IDF的评分策略,以确定哪些词最重要,应该被高亮。 **四、使用步骤** 1. ...

    lucene高亮显示

    Lucene通过`Highlighter`类来实现高亮显示。`Highlighter`类需要一个`QueryScorer`对象,该对象用于计算文档片段的得分,以及一个`Fragmenter`对象,用于将文本切分为片段。`SimpleHTMLFormatter`则用于将高亮的文本...

    传播智课Lucene+代码

    6. **高亮显示**:掌握如何使用Highlighter类来突出显示搜索结果中的匹配部分。 7. **更新和删除索引**:了解如何添加、更新和删除索引中的文档,以及提交更改的操作。 8. **性能优化**:探讨如何通过调整参数、使用...

    自己写的lucene分页高亮显示代码

    Lucene 提供了 `Highlighter` 工具类,用于高亮显示搜索结果中的匹配部分。以下步骤展示了如何使用高亮功能: 1. 创建一个 `Analyzer` 对象,用于分析文本。 2. 使用 `QueryParser` 解析查询字符串,得到 `Query` ...

    Lucene.Net_2_9_1+含高亮等包飘红

    3. **获取高亮器**: 创建一个Highlighter实例,传入FieldQuery、分片器和编码器。 4. **获取文档内容**: 通过Searcher找到匹配的文档,获取Document对象。 5. **生成高亮片段**: 使用Highlighter的...

    lucene.NET 中文分词

    本文将深入探讨Lucene.NET如何进行中文分词以及高亮显示的实现。 ### 1. 中文分词 中文分词是将连续的汉字序列切分成具有语义的词语的过程,是自然语言处理(NLP)中的基础步骤。在Lucene.NET中,为了支持中文分词...

    java实现lucene高亮显示Html,直接测试就可以用

    4. **高亮设置**:为了高亮显示,我们需要配置一个`Highlighter`,它会找到匹配的术语并应用高亮样式。`HighlighterUtils.java`中的`Highlighter`类可能是基于`SimpleHTMLFormatter`和`TermQueryHighlighter`,这两...

    整合Lucene搜索用户新闻项目实例,支持搜索关键词高亮

    本项目实例将详细介绍如何整合Lucene到一个用户新闻系统中,以实现高效的新闻搜索功能,并支持搜索关键词的高亮显示。 首先,我们需要了解Lucene的基本概念。Lucene是一个纯Java库,它提供了索引和搜索文本的工具,...

    lucene 学习实战系列(高亮+分页)

    6. 使用Highlighter高亮搜索结果的关键片段。 7. 实现分页逻辑,根据当前页数计算offset,然后调用search方法获取下一批ScoreDoc。 8. 渲染结果,展示高亮的搜索结果和分页导航。 五、总结 Lucene的高亮显示和分页...

    最新全文检索 lucene-5.2.1 入门经典实例

    在提供的"lucene5.2.1入门经典案例"中,你可以找到如何创建索引、执行查询、高亮显示结果等具体操作的示例代码。这些案例可以帮助初学者快速理解和应用Lucene-5.2.1的核心功能。通过实践,你可以更深入地了解Lucene...

    lucene第一步---5.中文分词IKAnalyzer和高亮highlighter的使用

    通过以上内容,我们可以了解到在Lucene中使用IKAnalyzer进行中文分词和利用Highlighter高亮搜索结果的关键点。这两个工具对于构建一个高效的中文搜索系统至关重要,它们使得用户能够更直观、准确地获取所需信息。

    lucene Demo(paoding)

    8. **高亮显示**:学习如何使用高亮工具,如`Highlighter`,来突出显示搜索结果中的匹配部分。 9. **性能优化**:探讨如何通过优化索引结构、合理设置缓存和批量操作等手段提升Lucene的性能。 10. **多线程索引和...

    用lucene实现摘要的高亮点

    本篇文章主要探讨如何利用Lucene实现文件摘要的自动提取,并进行关键词高亮显示。这一过程涉及到Lucene的Highlighter组件,它专门用于突出显示搜索结果中的关键词。 首先,我们了解Lucene的Highlighter是如何工作的...

    Lucene3.0增删改查和关键字高亮实例

    在这个“Lucene3.0增删改查和关键字高亮实例”项目中,我们将深入理解如何利用Lucene 3.0版本进行索引构建、文档的增删改查操作,并学习关键字高亮显示的实现方法。 首先,我们要了解**创建索引**的基本流程。在...

    paoding+lucene实现全文检索功能简单实例

    Lucene提供了Highlighter组件,能够分析查询结果并生成高亮的文本片段。你需要设置合适的高亮器,指定分词器和颜色样式,然后对每个匹配的文档段落进行高亮。 在实际应用中,你可能还需要考虑其他因素,如性能优化...

    lucene4.7 开发简单实例

    在本实例中,我们将深入探讨Lucene 4.7版本,涵盖索引的创建、修改、删除,以及查询时的排序、分页、优化和高亮显示等功能。此外,我们还将了解如何使用不同的分词器,以适应不同场景的需求。 首先,让我们从基础...

Global site tag (gtag.js) - Google Analytics