`

nutch开源搜索引擎的高亮和增加索引长度

阅读更多

高亮显示比较简单,网上也有很多介绍代码。修改如下:

将 org.apache.nutch.searcher.Summary 第 54行 代码 修改为:

 public String toString() { return "<span style='color:red'>" + super.toString() + "</span>"; }

增加索引长度花了我比较长的时间 , 不过后来发现原来有两个参数是专门调整索引长度的 ,刚看代码的时候没有注意到 ,在org.apache.nutch.searcher.Summarizer  的36行左右 有

  /** The number of context terms to display preceding and following matches.*/
  private static final int SUM_CONTEXT =
    NutchConf.get().getInt("searcher.summary.context", 5);

  /** The total number of terms to display in a summary.*/
  private static final int SUM_LENGTH =
    NutchConf.get().getInt("searcher.summary.length", 100);

这 两个 是  Term  的长度 , 第一个参数是 SUM_CONTEXT  在摘要中间最多有 5个 高亮显示的关键词(注:这里的NutchConf.get().getInt()第二个参数 5表示 默认值是5,也就是在取得searcher.summary.context为NULL时候给一个默认值),

第二个SUM_LENGTH  是在摘要中最多显示 100个 Term  ,这个Term 是分词得到的结果 ,在后面的摘要截取算法中需要用到 Term  ,不过可以通过Luncene 的保存Term的坐标 来实现 索引关键词的快速高亮显示 ,这样的好处是可以在查询的时候不再使用分词,以减少查询相应时间。

不过如果分词系统是基于词库的,则词库增长以后会有一定问题,这个以后在做专题讨论。

下面帖一下改过的算法内容,显示文字数大约在 150个左右 ,如果需要增加到更多 ,则可以修改 相应的代码。

 

 

/** *//** Returns a summary for the given pre-tokenized text. */
  
public Summary getSummary(String text, Query query) throws IOException ...{

    
// Simplistic implementation.  Finds the first fragments in the document
    
// containing any query terms.
    
//
    
// TODO: check that phrases in the query are matched in the fragment

    Token[] tokens 
= getTokens(text);             // parse text to token array

    
if (tokens.length == 0)
      
return new Summary();

    String[] terms 
= query.getTerms();
    HashSet highlight 
= new HashSet();            // put query terms in table
    for (int i = 0; i < terms.length; i++)
      highlight.add(terms[i]);

    
//
    
// Create a SortedSet that ranks excerpts according to
    
// how many query terms are present.  An excerpt is
    
// a Vector full of Fragments and Highlights
    
//
    SortedSet excerptSet = new TreeSet(new Comparator() ...{
        
public int compare(Object o1, Object o2) ...{
            Excerpt excerpt1 
= (Excerpt) o1;
            Excerpt excerpt2 
= (Excerpt) o2;

           
if (excerpt1 == null && excerpt2 != null...{
                
return -1;
            }
 else if (excerpt1 != null && excerpt2 == null...{
                
return 1;
            }
 else if (excerpt1 == null && excerpt2 == null...{
                
return 0;
            }


            
int numToks1 = excerpt1.numUniqueTokens();
            
int numToks2 = excerpt2.numUniqueTokens();

            
if (numToks1 < numToks2) ...{
                
return -1;
            }
 else if (numToks1 == numToks2) ...{
                
return excerpt1.numFragments() - excerpt2.numFragments();
            }
 else ...{
                
return 1;
            }

        }

    }

        );

    
//
    
// Iterate through all terms in the document
    
//
    int lastExcerptPos = 0;
    
for (int i = 0; i < tokens.length; i++...{
      
//
      
// If we find a term that's in the query...
      
//
      if (highlight.contains(tokens[i].termText())) ...{
        
//
        
// Start searching at a point SUM_CONTEXT terms back,
        
// and move SUM_CONTEXT terms into the future.
        
//
        int startToken = (i > SUM_CONTEXT) ? i-SUM_CONTEXT : 0;
        
int endToken = Math.min(i+SUM_CONTEXT*20, tokens.length);
        
int offset = tokens[startToken].startOffset();
        
int j = startToken;

        
//
        
// Iterate from the start point to the finish, adding
        
// terms all the way.  The end of the passage is always
        
// SUM_CONTEXT beyond the last query-term.
        
//
        Excerpt excerpt = new Excerpt();
        
if (i != 0...{
            excerpt.add(
new Summary.Ellipsis());
        }


        
//
        
// Iterate through as long as we're before the end of
        
// the document and we haven't hit the max-number-of-items
        
// -in-a-summary.
        
//
        Token a = null ;
        
while ((j < endToken) && (j - startToken < SUM_LENGTH)) ...{
          
//
          
// Now grab the hit-element, if present
          
//
          Token t = tokens[j];
          
if (highlight.contains(t.termText())) ...{
            excerpt.addToken(t.termText());
            
//System.out.println("Text:"+text.substring(offset, t.startOffset()) +" OffSet:"+offset +" Start:"+ t.startOffset());
            excerpt.add(new Fragment(text.substring(offset, t.startOffset())));
            excerpt.add(
new Highlight(text.substring(t.startOffset(),
                                          t.endOffset())));
            a 
= (Token)t.cloneToken() ;
            offset 
= a.endOffset();

            
//endToken = Math.min(j+SUM_LENGTH, tokens.length);
          }

          j
++;
        }


        
...{
           
...{
               
if(offset<text.length()&& Math.min(endToken,
                           i 
+ SUM_LENGTH)<tokens.length && tokens[Math.min(endToken,
                           i 
+ SUM_LENGTH)].endOffset()<text.length())
               
...{
                   excerpt.add(
new Fragment(text.substring(offset,
                                                           tokens[Math.min(endToken,
                           i 
+ SUM_LENGTH)].endOffset())));

               }

            }

        }



        lastExcerptPos 
= endToken;

        
//
        
// We found the series of search-term hits and added
        
// them (with intervening text) to the excerpt.  Now
        
// we need to add the trailing edge of text.
        
//
        
// So if (j < tokens.length) then there is still trailing
        
// text to add.  (We haven't hit the end of the source doc.)
        
// Add the words since the last hit-term insert.
        
//
//        if (j < tokens.length) {
//            System.out.println(text.length()+" Ooffset:"+offset + "  EndOff:"+ tokens[j].endOffset()+"  "+text );
//          excerpt.add(new Fragment(text.substring(offset,offset+tokens[j].endOffset())));
//        }

        
//
        
// Remember how many terms are in this excerpt
        
//
        excerpt.setNumTerms(j - startToken);

        
//
        
// Store the excerpt for later sorting
        
//
        excerptSet.add(excerpt);

        
//
        
// Start SUM_CONTEXT places away.  The next
        
// search for relevant excerpts begins at i-SUM_CONTEXT
        
//
        i = j+SUM_CONTEXT;
      }

    }


    
//
    
// If the target text doesn't appear, then we just
    
// excerpt the first SUM_LENGTH words from the document.
    
//
    if (excerptSet.size() == 0...{
        Excerpt excerpt 
= new Excerpt();
        
int excerptLen = Math.min(SUM_LENGTH, tokens.length);
        lastExcerptPos 
= excerptLen;

        excerpt.add(
new Fragment(text.substring(tokens[0].startOffset(), tokens[excerptLen-1].startOffset())));
        excerpt.setNumTerms(excerptLen);
        excerptSet.add(excerpt);
    }


    
//
    
// Now choose the best items from the excerpt set.
    
// Stop when our Summary grows too large.
    
//
    double tokenCount = 0;
    Summary s 
= new Summary();
    
while (tokenCount <= SUM_LENGTH && excerptSet.size() > 0...{
        Excerpt excerpt 
= (Excerpt) excerptSet.last();
        excerptSet.remove(excerpt);

        
double tokenFraction = (1.0 * excerpt.getNumTerms()) / excerpt.numFragments();
        
for (Enumeration e = excerpt.elements(); e.hasMoreElements(); ) ...{
            Fragment f 
= (Fragment) e.nextElement();
            
// Don't add fragments if it takes us over the max-limit
            if ((int)(tokenCount + tokenFraction) <= SUM_LENGTH) ...{
                s.add(f);
            }

            tokenCount 
+= tokenFraction;
        }

    }


    
if (tokenCount > 0 && lastExcerptPos < tokens.length)
      s.add(
new Ellipsis());
    
return s;
  }

 

jaddy0302 发表于2006-09-06 22:50:00  IP: 221.219.255.*
代码比较生猛 , 尤其是 计算超出参数约束的代码,修改需要更长的时候可以修改 int endToken = Math.min(i+SUM_CONTEXT*20, tokens.length);
不过 在 nutch-default.xml中间可以通过调整 searcher.summary.context 和 searcher.summary.length
 
dengyf 发表于2006-09-07 23:37:00  IP: 221.222.76.*
请问怎样nutch-0.8加中文分词,都是修改那些文件,谢谢
 
jaddy0302 发表于2006-09-08 21:00:00  IP: 125.96.24.*
只需要修改一个地方:
org.apache.nutch.analysis.NutchAnalysis
文件final public Query parse() throws ParseException 方法
的85行左右,修改为:
org.apache.lucene.analysis.TokenStream tokenizer = new com.xdtech.
util.lucene.XDChineseTokenizer(input);
分享到:
评论

相关推荐

    nutch解决搜索结果高亮和网页快照链接无效及网页变形

    Nutch 是一个开源的搜索引擎项目,它提供了网络爬虫、索引和搜索的功能。在构建一个自定义的搜索引擎时,可能会遇到几个常见的问题,如搜索结果的关键词高亮、快照链接无效以及网页在预览时的变形。下面将详细讨论...

    开源企业搜索引擎solr的应用教程

    《开源企业搜索引擎Solr的应用教程》 在当今信息爆炸的时代,高效、精准的搜索成为企业的核心竞争力之一。开源的企业搜索引擎Solr,凭借其强大的功能和灵活性,成为了许多组织的首选解决方案。本教程将深入探讨Solr...

    基于Apache Nutch和Solr等组件扩展实现对于AJAX加载类型页面的完整页面内容抓取,以及特定数据项的解析和索引

    最后,Apache Solr是基于Lucene的全文搜索引擎,用于建立高效的索引和查询服务。Nutch抓取并清洗的数据会被导入到Solr中,创建索引,使得我们可以快速搜索到目标信息。Solr支持复杂查询语法,可以实现精确匹配、模糊...

    lunece

    Nutch则是一个开源的Web搜索引擎项目,集成了爬虫、索引和搜索等功能,可以用来构建大规模的网络搜索引擎。 学习和使用Lucene,不仅可以掌握全文检索的基本原理,还能深入理解搜索引擎的内部运作机制,为构建自己的...

    一个专业搜索公司关于lucene和solar资料

    - “lucene”和“solr”分别代表了两个开源搜索平台:Apache Lucene和Apache Solr。 #### 内容概述 - **内容概览**: - **第1章 了解搜索引擎** - 介绍了搜索引擎的基本概念、Google的发展历程以及如何构建自己...

    lucene-8.2.zip

    分析器在两者之间起着桥梁作用,它将用户的输入分解为有意义的词汇单元,以便于索引和搜索。 2. **索引过程** 在Lucene 8.2中,索引过程包括文档的读取、分析、字段处理和倒排索引构建。倒排索引是Lucene的核心...

    lucene实现全文搜索

    它的创始人Doug Cutting也是著名搜索引擎Nutch和大数据框架Hadoop的创始人,目前在云计算公司CLOUDERA任职。 【Lucene应用详解】 在Lucene中,实现全文搜索涉及到以下几个关键概念: 1. **Document**:是Lucene中...

    Lucene相关资料

    它提供了一个高效、可扩展的基础架构,用于索引和搜索大量文本数据。本篇文章将从源码和工具的角度,深度解析Lucene的相关知识点。 1. **Lucene的基本概念** - **全文检索**:Lucene的核心功能是实现对文本数据的...

    Lucene实战 第二版 完整清晰中文版

    此外,书中还探讨了Lucene的Perl、Python、C#、.Net和C++的移植版本,并介绍了排序、过滤、项向量特性以及对多索引和远程索引的搜索操作。针对新引入的SpanQuery特性、扩展的查询解析器以及命中结果集等功能也进行了...

    BBS-Dev:复旦论坛的可扩展搜索引擎解决方案

    在这个解决方案中,Solr是核心的搜索引擎,负责对抓取的数据进行分析、索引和快速检索,为用户提供精准的搜索结果。 5. **Rails**:Rails是一个用Ruby语言编写的Web开发框架,强调“约定优于配置”和“DRY(Don't ...

    YouSeer-开源

    在YouSeer中,Solr被用作索引系统,负责对抓取的网页内容进行高效地索引和存储,支持复杂的查询操作和丰富的搜索特性,如近似搜索、拼写纠错、高亮显示等。 二、YouSeer的架构与工作流程 YouSeer的工作流程通常...

    一个专业搜索公司关于lucene+solar资料(1)

    - 本章详细介绍了构建搜索引擎所需的技术栈和关键组件,包括网络爬虫、全文索引构建以及用户界面设计等方面。 #### 三、数据获取技术 **3.1 自己的网络蜘蛛** - **3.1.1 BerkeleyDB介绍** - 是一种嵌入式数据库...

    solr基本总结

    - **定义**:Lucene 是一个基于 Java 的全文检索工具包,它可以为应用程序提供索引和搜索功能。 - **应用案例**:Lucene 被广泛应用于各种软件系统中,如 Eclipse 帮助系统的搜索功能。 - **与 Solr 的关系**:虽然 ...

    lucene笔记

    - **Nutch**: 是一个开源网络爬虫,结合了Lucene用于网页抓取和索引。 ### 5. 学习资源 - 官方文档: Apache Lucene的官方文档是学习Lucene的好起点。 - "Lucene in Action"书籍: 一本深入介绍Lucene的书籍,适合...

    Solr技术分析及运用

    **Solr** 是一个高度可扩展、高性能的开源搜索引擎平台,它基于 **Lucene** 构建而成,由 **Apache Software Foundation** 开发和维护。Solr 提供了一系列强大的功能,使其成为企业级搜索解决方案的理想选择。 1. *...

Global site tag (gtag.js) - Google Analytics