Lucene 3.6.2关键词高亮显示实现例子

* @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   
 */
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中文分词器。
     * @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();  
                }  
            }  
        }  
    }  
      
          
    /** 
     * 高亮的使用方式 
     */
    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("依赖");  
    }  
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值