其实nutch的评分机制有二部分,与通常的SE类似:
1。keywords匹配度
比如利用了lucene的similary机制,要索引和查询时均可定制。
2。page rank
这里有二个,
一是LinkAanlyzeScoring,作通常连接分析,但基本上都没有方法实现;不知道是否是opic的一个早期版本?
二是opic,即on-line importance computatioin。
这个与google的PageRanK是不同的,后者是off-line,可以说大大的不同。
包括inject,fetch,update,index等过程的score处理均在这样实现。
注意nutch使用的是一个varient of opic,所以其实它也不是严格按照其中的page所说来死套。
其中完整的opic代码如下 :
OPIC: On-line Page Importance Computation for each i let C[i] := 1/n ; for each i let H[i] := 0 ; let G:=0 ; do forever begin choose some node i ; %% each node is selected %% infinitely often H[i] += C[i]; %% single disk access per page for each child j of i, do C[j] += C[i]/out[i]; %% Distribution of cash %% depends on L G += C[i]; C[i] := 0 ; end
为什么pr这么重要呢?因为你搜索的上的就是找到合适,有用,规范的东西,或者说是high quality。这就是出发点,那么就有需要有机制去决策page的importance标准。其中质量高的pages不但要更新频繁些,就算在crawl阶段也要优先于是其它new discovered pages;再都就是搜索时更应该优先显示了。
当然百度也有自己的核心算法,所谓链接质量分析(李彦宏),不过觉得些东西大体上是类似的。自从很多论文,开源技术出来后大家也在模仿,说不定李彦宏也是模仿了xxx罢了!
最后还是来看看具体调用那些方法的地方,以便有问题时易于定位:
(注意QueryFilters是对具体的方法进行了代理,所以进入它分析即可)
一。injectedScore(url,datum)
>Injector.InjectorMapper中调用.注意这里是seed urls处理的地方。
如果url(per line in plain text)中没有指定score,则使用默认的1处理;
>FreeGenerator.FG(mapper)。当不需要首先添加到crawldb中而要生成fetchlist时使用。后续可能用到
filters:两者均无实现
二。generatorSortValue(url,datum,sort)
>Generator.Selector.map()。sort=1作为initSort,直接将inject的输出交给fitlers来处理
filters:两者均以datum.getScore() * sort。这样在输出时<sortvalue,datum>就产生了。
三。initialScore(url,datum) 对于新发现的urls設定
>FetcherThread.run() / handleRedirect() 。感觉就是在重定向时的设置?
>ParserOutputFormat.RecordWriter.write() 。(还是处于Fetcher阶段)它输出包括crawl_parse,parse_data,parse_data文件。
处理:将targetUrl置为status_link的datum.
>CrawlDbReducer 这是在crawldb update phase ,将新旧urls(包括crawldb/current,crawl_parse,crawl_fetch中的crawldatum)进行合并和状态更新。
处理:当状态为STATUS_LINKED才进行调用。
filters:均以设置为0(说是inlink的score会设置它)
passScoreBeforeParsing(Text url, CrawlDatum datum, Content content) copy score from datum to content for both filters.
>Fetcher.output() 在parsing一个页面的content前调用
>ArcSegmentCreator 同上
passScoreAfterParsing(Text url, Content content, Parse parse) copy score from content to parse for both filters.
>Fetcher.output() 在parsing一个页面的content后逐个url调用
>ArcSegmentCreator 同上
>ParseSegment.map() 在crawldb udpate前若需要parsing时调用;功能与fetcher.output()中一样
distributeScoreToOutlinks() 与updateDbScore()相对,将当前url 的crawl score分发所有outlinks。这过程应该先于updateDbScore()调用,因为理论上应该是先发现再被其它urls来update d。注意这里考虑了内链和外链的分开处理问题。
>ParserOutputFormat.RecordWriter.write() 。(还是处于Fetcher阶段 )在其中的initiateScore()后调用
updateDbScore(Text url, CrawlDatum old, CrawlDatum datum, List<CrawlDatum> inlinked)
OPICScoringFilter.java:
float adjust = 0.0f; //在已经存放的datum(url)的情况下,对所有后来的入链汇总scores到datum中 for (int i = 0; i < inlinked.size(); i++) { CrawlDatum linked = (CrawlDatum)inlinked.get(i); adjust += linked.getScore(); } if (old == null) old = datum; datum.setScore(old.getScore() + adjust);
>CrawlDbReducer.reduce() 在其中的initiateScore()后调用
indexerScore(Text, NutchDocument, dbDatum, fetchDatum, Parse, Inlinks, initScore) 将dbdatum中的score衰减,即power计算,然后再由initScore加权
>Indexer.index() -> IndexMapReduce.reduce()
references:
adaptive on-line page importance computation