`
lianshisheng
  • 浏览: 28221 次
  • 性别: 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+HighLighter高亮显示实例

    `src`目录存放源代码,`WebRoot`是Web应用程序的根目录,`.myeclipse`文件则是MyEclipse IDE的相关配置。 总之,Lucene+HighLighter的组合提供了强大的搜索和高亮功能,通过理解其工作原理和配置细节,开发者可以在...

    Lucene in action配套源代码

    4. **结果集处理**:源代码可能会展示如何处理返回的搜索结果,如高亮显示匹配的关键词,或者实现分页显示。 5. **更新与删除**:在索引生命周期中,可能会涉及到添加新的文档、更新现有文档或删除不再需要的文档。...

    lucene部分案例的源代码

    《Lucene案例源代码解析》 Lucene是一个高性能、全文本搜索库,广泛应用于各种信息检索系统中。本文将深入探讨“lucene部分案例的源代码”,解析其中的关键技术和应用场景,帮助读者更好地理解和运用Lucene。 一、...

    java实现高亮显示的jar包,lucene用的jar包

    首先,Lucene是Apache软件基金会的一个开放源代码项目,它提供了强大的文本分析和搜索功能。Lucene的核心组件包括索引和查询两个主要部分。索引阶段,Lucene将文档内容转换为倒排索引,以便快速查找匹配的文档。查询...

    IKAnalyzer LUCENE.4.9 中文分词的高亮显示

    在"src"和"lib"这两个文件夹中,"src"可能包含了项目的源代码,包括IKAnalyzer的配置和Lucene的索引创建、查询、高亮等操作的实现。"lib"可能包含了运行项目所需的依赖库,如IKAnalyzer的jar包和Lucene的库文件。 ...

    lucene4.9最全源代码

    通过深入学习和理解Lucene 4.9.0的源代码,开发者不仅可以掌握Lucene的基本用法,还能了解到其内部工作原理,进而能够定制自己的搜索解决方案,满足特定业务需求。同时,源代码中的注释和文档可以帮助我们更好地理解...

    lucene-4.8.0源代码,比较全

    本文将深入探讨Lucene 4.8.0版本的源代码,揭示其内部工作原理以及关键组件,帮助读者理解这个强大的搜索引擎是如何工作的。 一、Lucene概述 Lucene的核心概念包括文档(Document)、字段(Field)、索引(Index)...

    Lucene实战(第二版)源代码

    《Lucene实战(第二版)源代码》是关于Apache Lucene这一开源全文搜索引擎库的一份珍贵资源,包含了大量的示例代码和实现细节。Lucene是一个用Java编写的高性能、全文检索引擎库,它不是一个完整的搜索引擎,而是为...

    lucene搜索的简单入门例子源代码

    这个简单的例子展示了Lucene的基本工作流程,但实际应用中可能涉及更复杂的逻辑,如多字段搜索、模糊查询、排序、过滤器和高亮显示等。Lucene还支持分布式搜索,能够处理大规模的数据集。随着对Lucene的理解深入,你...

    lucene包,lucene实现核心代码

    Lucene是Apache软件基金会的一个开放源代码项目,它是一个全文搜索引擎库,主要用Java编写,但也有其他语言的版本。Lucene提供了高级的文本分析、索引和搜索功能,是构建高效、可扩展的信息检索应用的基础。在Java的...

    lucene.net完整源码

    本文将围绕“lucene.net完整源码”进行深入探讨,包括其分词机制、盘古分词的使用以及搜索关键词的高亮显示。 首先,我们来看Lucene.NET的核心——分词。在信息检索领域,分词是构建索引的基础步骤,它将文本分解...

    Lucene实战(中文版第二版)源代码

    《Lucene实战(中文版第二版)源代码》是一份宝贵的学习资源,它涵盖了Lucene在实际应用中的各种技术和策略。Lucene是一个高性能、全文本搜索库,由Apache软件基金会开发,广泛应用于搜索引擎的构建和其他需要高效...

    Lucene.Net 的桌面搜索源代码.rar

    **Lucene.Net 桌面搜索源代码解析** Lucene.Net 是一个开源的全文搜索引擎库,它是 Apache Lucene 的 .NET 版本。这个库允许开发者在 .NET 平台上构建高效、可扩展的搜索功能。它提供了强大的文本分析、索引和查询...

    Lucene搜索引擎开发权威经典源代码

    这本书结合源代码分析,详细介绍了如何利用Lucene进行信息检索和全文搜索的实现。Lucene是Apache软件基金会的一个开放源代码项目,它提供了一个高性能、可扩展的全文搜索引擎库,被广泛应用于各种数据检索场景。 ...

    传播智课Lucene+代码

    1. `[HeyJava][传智播客]全文检索Lucene.rar`:这可能是一个包含Lucene全文检索实现的视频课程或配套源代码。HeyJava通常与Java编程相关的教学内容有关,所以这可能是一个讲解如何在Java环境中使用Lucene进行全文...

    Lucene与数据库结合示例(加双关键字高亮)

    Lucene是Apache软件基金会的一个开放源代码项目,它提供了一个高性能、可扩展的信息检索库。这个标签说明了文章的核心技术是围绕Lucene进行的,可能包括Lucene的安装、配置、索引创建、查询解析、搜索执行等步骤。 ...

    Lucene In Action随书源代码

    通过分析《Lucene In Action》的源代码,我们可以了解到以下几个关键知识点: 1. **索引构建**:Lucene的索引过程涉及到文档分析、词项创建和倒排索引的构建。源代码会展示如何使用Analyzer对文本进行分词,以及...

    《lucene搜索引擎开发权威经典》一书的光盘源代码

    《lucene搜索引擎开发权威经典》一书的光盘源代码包含了大量的示例和实践项目,是深入了解和学习Apache Lucene搜索引擎技术的重要资源。Lucene是一个高性能、全文本搜索库,由Java编写,广泛应用于各种搜索应用中。...

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

    "luceneDemo"可能是项目源代码,包含整合Lucene的具体实现,如创建索引、执行搜索以及关键词高亮等逻辑。 总之,这个项目实例涵盖了从数据库获取新闻数据,使用Lucene进行文本处理、索引构建、搜索执行,到最后的...

    lucune3.0 及高亮显示 所需的包及代码

    标签“源码”表明内容可能涉及到Lucene 3.0的源代码分析,这对于开发者来说是深入理解其工作原理和定制功能的关键。而“工具”可能意味着博主分享了一些辅助开发的工具或技巧,例如使用IDE插件来更好地集成和调试...

Global site tag (gtag.js) - Google Analytics