Nutch- 0.8.1 中summary出错报告
出错问题描述:
Nutch- 0.8.1 中,中文分词采用的单字分法。搜索时返回的摘要以字为单位显示高亮。如搜索“媒体”,摘要中所有的单独的“媒”和“体”都会高亮。
搜索引擎中已经加入了中文分词后,不会出现Nutch- 0.8.1 中的高亮错误。但有时会出现返回的摘要中无关键字的错误。如搜索“东西”,会返回如下条目,题目和摘要中都没有出现“东西”。点击进入该网页后发现网页中存在“东西”字段。
Nutch 在搜索时和searcher包相关的基本流程
在tomcat下运行Nutch,搜索时,首先将用户提交的搜索关键字提交给search.jsp,然后进行如下工作:
1. 将存储查询字段的string querystring通过Query类中的parse方法生成query对象,此阶段完成了对查询字段的分词。
2.建立Nutchbean的对象bean,以query为参数使用seach接口取得hits。
3.以hits的起始位置和hits的结束位置为参数使用hits的getHits方法取得hit的所有对象存储于Hit[]的对象show中。
4.以show为参数使用bean的getDetail方法取得detail的所有对象存储于HitDetails[]的对象details中。
5.以details和query为参数使用bean的getSummary方法取得所有summary对象存储于summary[ ]的对象summaries中。
Summary的生成
Summary的结构
1:碎片部分(Summary.Fragment
)
为指定数目的关键字附近的词语。
2:省略部分(Summary.Ellipsis
)
…
3:高亮部分(Summary.Highlight
)
经过分词的查询短语中的任何一个词。
生成Summary的两个接口
Summary的生成是在nutchbean中使用HitSummerizer以及Summarizer的接口。
HitSummerizer:根据HitDetails为查询关键字建立一个摘要,getSummary的参数类型为
HitDetails, Query
Summarizer:在指定的String中为查询关键字建立一个摘要,getSummary的参数类型为
String, Query
具体实现:
在FetchedSegments.java中,传递hitDetails给HitSummerizer,由文本分析器对提取到的hitDetails中的content信息进行分析得到文本内容,将文本内容传递给Summarizer,由Summarizer根据查询关键字摘取高亮部分后,构建并返回summary。
生成摘要各类之间的继承和调用关系
NutchBean---àFetchedSegments--àSummarizerFactory
SummarizeFactory建立了一个使用插件的extension, 目前使用的插件为org.apache.nutch.summary.basic
Details的生成
summary是根据details和query生成的。Details是由indexSercher中实现hitDetails接口来获得的。具体是从hits[]中取出每个hit存储在hitDetails[]中。
Text的生成
在FetchedSegments中,实现Summarizer接口传递的参数 String text是由Details生成的。具体生成方法为:
getSegment(details).getParseText(getUrl(details)).getText();
即取得details所在的segment,根据details中的url域从detail所在的segment中获得该url对应的ParseText(经过分词的文本)。
综上所述,text的获得流程为:get hitàget detailsàget text
summary.basic插件实现获得摘要功能的步骤:
插件中有两个属性:
sumContext:用来指定从查询字段两边取词的个数,即用以生成片段的词的个数;
sumLength:摘要的最大总长度;
插件实现getSummary方法的步骤
将text放入token[]中,这里通过org.apache.lucene.analysis包对text进行分词,分词的结果存于token[]中。如token长度为0,返回空summary。Token_deep设定了token的最大长度。超过长度的文本将会被抛弃。
将query中需要被高亮部分存于String[] terms中,这里调用query类的getTerms方法,该方法实现功能如下:判断如果用户查询的字段不是停用词,并且是经过分词处理,则将结果添到列表中,然后将列表内容保存于字符串数组中。
将需要被高亮的部分存入Hashset highlight中。
建立list excerpts,从token[1]至token[token.length]获得summary的3个部分并存储于类excerpt中,并将获得的每一个excerpt添加到excerpts列表中。
获得summary 3个部分的具体算法:
如果发现token中有关键字,取出关键字两边的sumContext个数的词。并添加省略。
Excerpt中的内容:
片段 sumContext |
高亮 |
片段 sumContext |
… |
将excerpt在excerpts列表中按照分数排序。
如果列表excerpts的大小为0,即在token中没有找到任何查询词,则从片段中建立一个sum_Length长度的字段。存储于excerpts中。
取最好的expert建立best excerpts列表直到达到sum_Length指定的长度。
用best excerpts 列表建立summary。
关于目前摘要出错问题的原因和解决
出错原因:是页面的文本内容产生的token数目超过了token_deep的值,导致包含关键字的文本部分被抛弃,因此summary取的是页面文本第一个summary_length的长度。解决办法:
1. 加大token_deep的值。或者干脆去掉这个限制。
2. 不使用summary-basic摘要插件,转而使用nutch提供的另外一个生成summary的插件org.apache.nutch.summary.lucene。
附:summary.basic插件实现getSummary方法的流程图:
Token.l=0 |
Queryàterms |
Termsàhighlight |
Build excerpts |
Sort excerpt |
Textàtoken |
Highlight contain token
|
Build best excerpts |
Return new summary |
Build summary And return |
Excerpts=null |
Build excerpts with no highlight |
Yes |
Yes |
No |
No |
Tips:
1 关于hit,hitDetails中存储的东西
Hit是一个符合查询内容的映射:查询关键字→命中页面
HitDetail存储hit所命中页面的相关信息,例如页面存在于哪个segment,索引号,URL,其他属性值等,field[]存储属性名称,value[]存储对应的属性值。
2 关于高亮在哪里做的
Summary中的toHtml方法中对高亮部分增加了高亮标签。
在页面显示时searcher.jsp调用了toHtml方法。
3 关于URL的存储格式
url以UTF8格式存储。UTF8是以8bits为编码的最基本单位。
4 关于segments的存储格式
HashMap
5 关于ant的使用
直接执行apt-get install ant命令安装。自己下载后安装会遇到配置问题。
6 关于对插件的修改,修改插件并ant后,需要将nutch目录下的plugins文件夹删掉或改名,否则加载时还是优先加载的修改前的,即nutch目录下的plugins和.job,而不是build目录下的新构建的文件。