`
lianshisheng
  • 浏览: 27656 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Lucene源代码之高亮显示

阅读更多

慢慢开始读Lucene源代码,首先就从高亮显示开始吧,因为最近才看过这个,而且好像是新版本后来加上的。

我的方案:从实例逐一解决源代码。

需要分析的实例代码:

package org.apache.lucene.search.highlight; 

import java.io.IOException; 
import java.io.StringReader; 

import junit.framework.TestCase; 

import org.apache.lucene.analysis.Analyzer; 
import org.apache.lucene.analysis.TokenStream; 
import org.apache.lucene.analysis.standard.StandardAnalyzer; 
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.queryParser.QueryParser; 
import org.apache.lucene.search.Hits; 
import org.apache.lucene.search.IndexSearcher; 
import org.apache.lucene.search.Query; 
import org.apache.lucene.search.Searcher; 
import org.apache.lucene.store.RAMDirectory; 

public class HighlighterTest extends TestCase  
{ 
    private IndexReader reader; 
    private static final String FIELD_NAME = "contents"; 
    private Query query; 
    RAMDirectory ramDir; 
    public Searcher searcher = null; 
    public Hits hits = null; 
    int numHighlights = 0; 
    Analyzer analyzer=new StandardAnalyzer(); 
    QueryScorer queryScorer=null; 

    String texts[] = 
        { 
            "Hello this is a piece of text that is very long and contains too much preamble and the meat is really here which says kennedy has been shot", 
            "This piece of text refers to Kennedy at the beginning then has a longer piece of text that is very long in the middle and finally ends with another reference to Kennedy", 
            "JFK has been shot", 
            "John Kennedy has been shot", 
            "This text has a typo in referring to Keneddy" }; 

    public HighlighterTest(String arg0) 
    { 
        super(arg0); 
    } 

    public void testSimpleHighlighter() throws Exception 
    { 
        doSearching("Kennedy"); 
        queryScorer=new QueryScorer(query);                                     //one 
        Highlighter highlighter =new Highlighter(queryScorer);             //two 
        highlighter.setTextFragmenter(new SimpleFragmenter(100));    //three 
        int maxNumFragmentsRequired =20; 
        for (int i = 0; i < hits.length(); i++) 
        { 
            String text = hits.doc(i).get(FIELD_NAME); 
            TokenStream tokenStream=analyzer.tokenStream(FIELD_NAME,new StringReader(text)); //four 

            String result = 
                highlighter.getBestFragments(tokenStream,text,maxNumFragmentsRequired, "...");       //five 
            System.out.println("\t" + result); 
        } 
    } 

    public void doSearching(String queryString) throws Exception 
    { 
        QueryParser parser=new QueryParser(FIELD_NAME, new StandardAnalyzer()); 
        query = parser.parse(queryString); 
        doSearching(query); 
    } 
    public void doSearching(Query unReWrittenQuery) throws Exception 
    { 
        searcher = new IndexSearcher(ramDir); 

        /* 
         * 在将Query实例传递到QueryScorer之前,可以调用 
         * Query.rewrite(IndexReader)方法来重写Query对象 
         * (否则,你必须确保用户输入的查询文本就是Lucene直接可以处理最基本的项)。 
         */ 
        query=unReWrittenQuery.rewrite(reader); 
         
        System.out.println("Searching for: " + query.toString(FIELD_NAME)); 
        hits = searcher.search(query); 
    }    

    /* 
     * @see TestCase#setUp() 
     */ 
    protected void setUp() throws Exception 
    { 
        ramDir = new RAMDirectory(); 
        IndexWriter writer = new IndexWriter(ramDir, new StandardAnalyzer(), true); 
        for (int i = 0; i < texts.length; i++) 
        { 
            addDoc(writer, texts); 
        } 

        writer.optimize(); 
        writer.close(); 
        reader = IndexReader.open(ramDir); 
        numHighlights = 0; 
    } 

    private void addDoc(IndexWriter writer, String text) throws IOException 
    { 
        Document d = new Document(); 
        Field f = new Field(FIELD_NAME, text,Field.Store.YES, Field.Index.TOKENIZED); 
        d.add(f); 
        writer.addDocument(d); 

    } 

    /* 
     * @see TestCase#tearDown() 
     */ 
    protected void tearDown() throws Exception 
    { 
        super.tearDown(); 
    } 

} 

 

上文是运用Junit来测试单元的,主要用到的类有:

QueryScorer;

HighLight;同时衍生出很多不同的类和接口。

整体内容如下:

Highlighter包括了三个主要部分:段划分器(Fragmenter)、计分器(Scorer)和格式化器(Formatter)。这几个部分对应于Java的同名接口,并且每部分都有一个内置的实现以便我们使用。最简单的Highlighter将返回在 匹配项周围的最佳段落,并使用HTML的<B>将这些项标记出来:

String text = “The quick brown fox jumps over the lazy dog”;
TermQuery query = new TermQuery(new Term(“field”, “fox”));
Scorer scorer = new QueryScorer(query);
Highlighter highlighter = new Highlighter(scorer);
TokenStream tokenStream =
new SimpleAnalyzer().tokenStream(“field”,
new StringReader(text));
System.out.println(highlighter.getBestFragment(tokenStream,text));
前述代码将产生如下输出

The quick brown <B>fox</B> jumps over the lazy dog

Highlighter 不仅需要你提供记分器和需要高亮显示的文本,还需要一个TokenStream实例。这个TokenStream实例是由分析器生成的。为了成功地对项进 行高亮显示,Query中的这些项需要匹配TokenStream产生的Token实例。我们提供的文本则被用于生成TokenStream,而这个 TokenStream又被用作高亮显示的原始文本。每个由TokenStream生成的Token实例都包含语汇单元的位置信息,这些信息用来指示原始 文本中高亮部分的起始和结束位置。

Highlighter利用Fragmenter将原始文本分割成多个片段。内置的SimpleFragmenter将原始文本分割成相同大小的片段,片段默认的大小为100个字符。这个大小是可控制的。

QueryScorer 是内置的计分器。计分器的工作首先是将片段排序。QueryScorer使用的项是从用户输入的查询中得到的;它会从原始输入的单词、词组和布尔查询中提 取项,并且基于相应的加权因子(boost factor)给它们加权。为了便于QueryScoere使用,还必须对查询的原始形式进行重写。比如,带通配符查询、模糊查询、前缀查询以及范围查询 等,都被重写为BoolenaQuery中所使用的项。在将Query实例传递到QueryScorer之前,可以调用Query.rewrite (IndexReader)方法来重写Query对象(否则,你必须确保用户输入的查询文本就是Lucene直接可以处理最基本的项)。

最后,格式化器(Formatter)用于装饰项文本。如果不指定其他的格式化器,Lucene会默认使用内置的格式化器 SimpleHTMLFormatter,这个格式化器将会用HTML的黑体开始标签(begin bold tags <B>)和黑体结束标签(end bold tags </B>)来标识出高亮显示的项文本。Highlighter默认地使用SimpleHTMLFormatter和 SimpleFragmenter这两个格式化器。每一个由Formatter高亮显示的项都将会带有一个语汇单元评分。当使用QueryScorer 时,这个评分将作为查询该项的加权因子。这个语汇单元评分能够被用来决定该项的重要性。要利用这个特性就必须实现自定义的格式化器。

分享到:
评论

相关推荐

    lucene.net完整源码

    分词、盘古分词、搜索关键词高亮显示。包含了lucene的基本操作

    傻瓜索引搜索v1.1[含全部源代码]

    没有高亮显示这个部分。所以想要的话还要再开发。 是 http://download.csdn.net/detail/raykenio/3896011 这个地址的程序源代码。唯一不同是源代码升级到了.Net 4.0下。如果要恢复成.Net 2.0只要改变Lucene.Net.DLL...

    JAVA上百实例源码以及开源项目源代码

    Java波浪文字制作方法及源代码 1个目标文件 摘要:Java源码,初学实例,波浪文字 Java波浪文字,一个利用Java处理字符的实例,可以设置运动方向参数,显示文本的字符数组,高速文本颜色,显示字体的 FontMetrics对象,...

    后端开发-搜索引擎的设计与实现

    【论文+源代码+ppt+教程】 经过对搜索引擎的研究同时与Lucene自身的特性相结合,搜索引擎的设计与实现需要实现的功能阐述如下: (1)支持桌面文件搜索,格式包括txt、doc、xls和ppt; (2)支持分词查询 (3)支持...

    Java毕业设计-基于Lucene库开发的搜索引擎的设计与实现-论文+源代码+数据库(超全资料).rar

    该引擎能够对海量文档进行快速索引和检索,提供全文搜索、关键词高亮显示、多条件过滤等实用功能。同时,系统支持用户自定义搜索规则,满足不同场景下的搜索需求。此外,项目还具备良好的扩展性,便于未来功能的优化...

    Lucene 3.6.1完整案例

    Lucene 3.6.1: 中文分词、创建索引库、排序、多字段分页查询以及高亮显示源 希望对大家有帮助, 我自己建立的mysql数据库 使用了IKAnalyzer分词器源代码,大家可以自己设置停词,也可以自己改写算法

    搜索引擎的设计与实现(含源代码)

    经过对搜索引擎的研究同时与Lucene自身的特性相结合,搜索引擎的设计与实现需要实现的功能阐述如下: (1)支持桌面文件... (4)能够高亮显示搜索关键字 (5)显示查询所用的时间 (6)显示搜索历史、过滤关键字

    基于SSM的个人博客+源代码+文档说明

    在线编辑器使用了百度的UEditor,支持单图,多图上传,支持截图上传,支持代码高亮特性 &lt;项目介绍&gt; 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用...

    毕业设计-基于Java实现搜索引擎设计

    经过对搜索引擎的研究同时与Lucene自身的特性相结合,搜索引擎的设计与实现需要实现的功能阐述...内附完整的项目源代码、项目执行截图、项目讲解、毕业设计文档/PPT等完整的毕业设计资料 希望能对你的学习有一点帮助

    搜索引擎的设计与实现【源代码+数据库+论文+视频讲解部署】.rar

    经过对搜索引擎的研究同时与Lucene自身的特性相结合,搜索引擎的设计与实现需要实现的功能阐述如下: (1)支持桌面文件... (4)能够高亮显示搜索关键字 (5)显示查询所用的时间 (6)显示搜索历史、过滤关键字

    毕业设计,搜索引擎的设计与实现,Java完整源代码,内含毕业论文、开题报告、毕业答辩PPT、数据库脚本以及项目辅导视频

    经过对搜索引擎的研究同时与Lucene自身的特性相结合,搜索引擎的设计与实现... (4)能够高亮显示搜索关键字 (5)显示查询所用的时间 (6)显示搜索历史、过滤关键字 数据库:SQL Server 使用技术:Lucence + JSP

    搜索引擎的设计与实现(源码+数据库sql+lun文+视频).rar

    搜索引擎的设计与实现的源代码和论文由学员提供.... 经过对搜索引擎的研究同时与Lucene自身的特性相结合,搜索引擎的设计与实现需要实现的功能阐述如下: (1)支持桌面文件搜索,格式包括txt、doc、xls和ppt; ...

    JAVA上百实例源码以及开源项目

     Java绘制图片火焰效果,源代码相关注释:前景和背景Image对象、Applet和绘制火焰的效果的Image对象、Applet和绘制火焰的效果的Graphics对象、火焰效果的线程、Applet的高度,图片到图片装载器、绘制火焰效果的X坐标...

    搜索引擎设计软件程序源码+数据库+WORD毕业设计论文文档.zip

    (4)能够高亮显示搜索关键字 (5)显示查询所用的时间 (6)显示搜索历史、过滤关键字 目 录 目 录 IV 1 绪论 1 1.1 项目背景 1 1.2 国内外发展现状及分类 2 1.3 本论文组织结构介绍 3 2 相关技术介绍 5 2.1...

    Hbase 二级索引方案

    源代码。Lily HBase Indexer 使用 SolrCloud 来存储 HBase 的索引数据,当 HBase 执行写 入、更新或删除操作时,Indexer 通过 HBase 的 replication 功能来把这些操作抽象成一系 列的 Event 事件,并用来保证写入 ...

    java开源包8

    JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor ...

    java开源包10

    JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor ...

    java开源包1

    JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor ...

    java开源包11

    JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor ...

Global site tag (gtag.js) - Google Analytics