【Lucene3.6.2入门系列】第11节_高亮
2013-08-20 11:24
281 查看
package com.jadyer.lucene; import java.io.File; import java.io.IOException; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.queryParser.MultiFieldQueryParser; import org.apache.lucene.queryParser.QueryParser; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TopDocs; import org.apache.lucene.search.highlight.Formatter; import org.apache.lucene.search.highlight.Fragmenter; import org.apache.lucene.search.highlight.Highlighter; import org.apache.lucene.search.highlight.QueryScorer; import org.apache.lucene.search.highlight.SimpleHTMLFormatter; import org.apache.lucene.search.highlight.SimpleSpanFragmenter; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.apache.lucene.util.Version; import org.apache.tika.Tika; import com.chenlb.mmseg4j.analysis.MMSegAnalyzer; /** * 【Lucene3.6.2入门系列】第11节_高亮 * @see 高亮功能属于Lucene的扩展功能(或者叫做贡献功能) * @see 其所需jar位于Lucene-3.6.2.zip中的/contrib/highlighter/文件夹中 * @see 本例中需要以下4个jar * @see lucene-core-3.6.2.jar * @see lucene-highlighter-3.6.2.jar * @see mmseg4j-all-1.8.5-with-dic.jar * @see tika-app-1.4.jar * @create Aug 7, 2013 11:37:10 AM * @author 玄玉<http://blog.csdn.net/jadyer> */ public class HelloHighLighter { private Directory directory; private IndexReader reader; public HelloHighLighter(){ Document doc = null; IndexWriter writer = null; try{ directory = FSDirectory.open(new File("myExample/myIndex/")); writer = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_36, new MMSegAnalyzer())); writer.deleteAll(); for(File myFile : new File("myExample/myFile/").listFiles()){ doc = new Document(); doc.add(new Field("filecontent", new Tika().parse(myFile))); //Field.Store.NO,Field.Index.ANALYZED doc.add(new Field("filepath", myFile.getAbsolutePath(), Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS)); writer.addDocument(doc); } }catch(Exception e) { e.printStackTrace(); }finally{ if(null != writer){ try { writer.close(); } catch (IOException ce) { ce.printStackTrace(); } } } } /** * 获取IndexSearcher实例 */ private IndexSearcher getIndexSearcher(){ try { if(reader == null){ reader = IndexReader.open(directory); }else{ //if the index was changed since the provided reader was opened, open and return a new reader; else,return null //如果当前reader在打开期间index发生改变,则打开并返回一个新的IndexReader,否则返回null IndexReader ir = IndexReader.openIfChanged(reader); if(ir != null){ reader.close(); //关闭原reader reader = ir; //赋予新reader } } return new IndexSearcher(reader); }catch(Exception e) { e.printStackTrace(); } return null; //发生异常则返回null } /** * 高亮搜索 * @see 高亮搜索时,不建议把高亮信息存到索引里,而是搜索到内容之后再进行高亮处理 * @see 这里用的是MMSeg4j中文分词器,有关其介绍详见http://blog.csdn.net/jadyer/article/details/10049525 * @param expr 搜索表达式 */ public void searchByHignLighter(String expr){ Analyzer analyzer = new MMSegAnalyzer(); IndexSearcher searcher = this.getIndexSearcher(); //搜索多个Field QueryParser parser = new MultiFieldQueryParser(Version.LUCENE_36, new String[]{"filepath", "filecontent"}, analyzer); try { Query query = parser.parse(expr); TopDocs tds = searcher.search(query, 50); for(ScoreDoc sd : tds.scoreDocs){ Document doc = searcher.doc(sd.doc); //获取文档内容 String filecontent = new Tika().parseToString(new File(doc.get("filepath"))); System.out.println("搜索到的内容为[" + filecontent + "]"); //开始高亮处理 QueryScorer queryScorer = new QueryScorer(query); Fragmenter fragmenter = new SimpleSpanFragmenter(queryScorer, filecontent.length()); Formatter formatter = new SimpleHTMLFormatter("<span style='color:red'>", "</span>"); Highlighter hl = new Highlighter(formatter, queryScorer); hl.setTextFragmenter(fragmenter); System.out.println("高亮后的内容为[" + hl.getBestFragment(analyzer, "filecontent", filecontent) + "]"); } } catch (Exception e) { e.printStackTrace(); } finally { if(null != searcher){ try { searcher.close(); //记得关闭IndexSearcher } catch (IOException e) { e.printStackTrace(); } } } } /** * 高亮的使用方式 * @see 这里用的是MMSeg4j中文分词器,有关其介绍详见http://blog.csdn.net/jadyer/article/details/10049525 */ private static void testHighLighter(){ String fieldName = "myinfo"; //这个可以随便写,就是起个标识的作用 String text = "我来自中国黑龙江省哈尔滨市巴彦县兴隆镇长春乡民权村4队"; QueryParser parser = new QueryParser(Version.LUCENE_36, fieldName, new MMSegAnalyzer()); try { //MMSeg4j的new MMSegAnalyzer()默认只会对'中国'和'兴隆'进行分词,所以这里就只高亮它们俩了 Query query = parser.parse("中国 兴隆"); //针对查询出来的文本,查询其评分,以便于能够根据评分决定显示情况 QueryScorer queryScorer = new QueryScorer(query); //对字符串或文本进行分段,SimpleSpanFragmenter构造方法的第二个参数可以指定高亮的文本长度,默认为100 Fragmenter fragmenter = new SimpleSpanFragmenter(queryScorer); //高亮时的高亮格式,默认为<B></B>,这里指定为红色字体 Formatter formatter = new SimpleHTMLFormatter("<span style='color:red'>", "</span>"); //Highlighter专门用来做高亮显示 //该构造方法还有一个参数为Encoder,它有两个实现类DefaultEncoder和SimpleHTMLEncoder //SimpleHTMLEncoder可以忽略掉HTML标签,而DefaultEncoder则不会忽略HTML标签 Highlighter hl = new Highlighter(formatter, queryScorer); hl.setTextFragmenter(fragmenter); System.out.println(hl.getBestFragment(new MMSegAnalyzer(), fieldName, text)); } catch (Exception e) { e.printStackTrace(); } } /** * 小测试一下 */ public static void main(String[] args) { //测试高亮的基本使用效果 HelloHighLighter.testHighLighter(); //测试高亮搜索的效果(测试前记得在myExample/myFile/文件夹中准备一个或多个内容包含"依赖"的doc或pdf的等文件) new HelloHighLighter().searchByHignLighter("依赖"); } }
相关文章推荐
- 【Lucene3.6.2入门系列】第11节_高亮
- 【Lucene3.6.2入门系列】第15节_SolrJ高亮
- 【Lucene3.6.2入门系列】第04节_中文分词器
- 【Lucene3.6.2入门系列】第15节_SolrJ高亮
- 【Lucene3.6.2入门系列】第12节_近实时搜索
- 【Lucene3.6.2入门系列】第03节_简述Lucene中常见的搜索功能
- 【Lucene3.6.2入门系列】第01节_HelloWord
- 【Lucene3.6.2入门系列】第13节_Solr3.6.2简介以及整合Tomcat
- Lucene 3.6.2入门系列:高级搜索之自定义QueryParser
- 【Lucene3.6.2入门系列】第08节_高级搜索之自定义评分
- 【Lucene3.6.2入门系列】第14节_SolrJ操作索引和搜索文档以及整合中文分词
- 【Lucene3.6.2入门系列】第12节_近实时搜索
- 【Lucene3.6.2入门系列】第15节_SolrJ高亮
- Lucene 3.6.2入门: 高亮
- 【Lucene3.6.2入门系列】第04节_中文分词器
- 【Lucene3.6.2入门系列】第09节_高级搜索之自定义QueryParser
- 【Lucene3.6.2入门系列】第02节_针对索引文件的CRUD
- 【Lucene3.6.2入门系列】第05节_自定义停用词分词器和同义词分词器
- 【Lucene3.6.2入门系列】第10节_Tika
- 【Lucene3.6.2入门系列】第03节_简述Lucene中常见的搜索功能