一、各个主要类之间的关系
SolrIndexerJob extends IndexerJob
1、IndexerJob:主要完成
2、SolrIndexerJob:主要完成
3、IndexUtil:主要只有一个方法public NutchDocument index(String key, WebPage page),用于根据网页信息,返回一个solr的Document对象。

二、程序调用流程

查看Nutch中的执行脚本--nutch,得到以下信息:
elif [ "$COMMAND" = "solrindex" ] ; then

CLASS=org.apache.nutch.indexer.solr.SolrIndexerJob
因此程序入口位于SolrIndexerJob类中。

(一)org.apache.nutch.indexer.SolrIndexerJob
1、程序入口
  public static void main(String[] args) throws Exception {
final int res = ToolRunner.run(NutchConfiguration.create(),
new SolrIndexerJob(), args);
System.exit(res);
}

使用了ToolRunner.run()来执行程序,可参考:使用ToolRunner运行Hadoop程序基本原理分析

其中第一个参数主要是加载了nutch相关的参数,主要包括hadoop的core-default.xml、core-site.xml以及nutch的nutch-default.xml、nutch-site.xml。

第二个参数指明了运行SolrIndexerJob的run(String[])方法.

2、执行SolrIndexerJob类的run(String[])方法
  
  public int run(String[] args) throws Exception {
if (args.length < 2) {
System.err.println("Usage: SolrIndexerJob <solr url> (<batchId> | -all | -reindex) [-crawlId <id>]");
return -1;
} if (args.length == 4 && "-crawlId".equals(args[2])) {
getConf().set(Nutch.CRAWL_ID_KEY, args[3]);
}
try {
indexSolr(args[0], args[1]);
return 0;
} catch (final Exception e) {
LOG.error("SolrIndexerJob: " + StringUtils.stringifyException(e));
return -1;
}
}

先判断参数的合理性,然后执行执行indexSolr(String,String)方法。


3、执行indexSolr(String,String)方法
  
public void indexSolr(String solrUrl, String batchId) throws Exception {
LOG.info("SolrIndexerJob: starting"); run(ToolUtil.toArgMap(
Nutch.ARG_SOLR, solrUrl,
Nutch.ARG_BATCH, batchId));
// do the commits once and for all the reducers in one go
getConf().set(SolrConstants.SERVER_URL,solrUrl);
SolrServer solr = SolrUtils.getCommonsHttpSolrServer(getConf());
if (getConf().getBoolean(SolrConstants.COMMIT_INDEX, true)) {
solr.commit();
}
LOG.info("SolrIndexerJob: done.");
}

4、执行run(Map<...>)方法 
@Override
public Map<String,Object> run(Map<String,Object> args) throws Exception {
String solrUrl = (String)args.get(Nutch.ARG_SOLR);
String batchId = (String)args.get(Nutch.ARG_BATCH);
NutchIndexWriterFactory.addClassToConf(getConf(), SolrWriter.class);
getConf().set(SolrConstants.SERVER_URL, solrUrl); currentJob = createIndexJob(getConf(), "solr-index", batchId); currentJob.waitForCompletion(true);
ToolUtil.recordJobStatus(null, currentJob, results);
return results;
}


(二)org.apache.nutch.indexer.IndexerJob
1、执行createIndexJob()方法。
  protected Job createIndexJob(Configuration conf, String jobName, String batchId)
throws IOException, ClassNotFoundException {
conf.set(GeneratorJob.BATCH_ID, batchId);
Job job = new NutchJob(conf, jobName);
// TODO: Figure out why this needs to be here
job.getConfiguration().setClass("mapred.output.key.comparator.class",
StringComparator.class, RawComparator.class); Collection<WebPage.Field> fields = getFields(job);
StorageUtils.initMapperJob(job, fields, String.class, NutchDocument.class,
IndexerMapper.class);
job.setNumReduceTasks(0);
job.setOutputFormatClass(IndexerOutputFormat.class);
return job;
}
}

2、执行map相关的方法,包括setup(),map(),cleanup()
  public static class IndexerMapper
extends GoraMapper<String, WebPage, String, NutchDocument> {
public IndexUtil indexUtil;
public DataStore<String, WebPage> store; protected Utf8 batchId; @Override
public void setup(Context context) throws IOException {
Configuration conf = context.getConfiguration();
batchId = new Utf8(conf.get(GeneratorJob.BATCH_ID, Nutch.ALL_BATCH_ID_STR));
indexUtil = new IndexUtil(conf);
try {
store = StorageUtils.createWebStore(conf, String.class, WebPage.class);
} catch (ClassNotFoundException e) {
throw new IOException(e);
}
} protected void cleanup(Context context) throws IOException ,InterruptedException {
store.close();
}; @Override
public void map(String key, WebPage page, Context context)
throws IOException, InterruptedException {
ParseStatus pstatus = page.getParseStatus();
if (pstatus == null || !ParseStatusUtils.isSuccess(pstatus)
|| pstatus.getMinorCode() == ParseStatusCodes.SUCCESS_REDIRECT) {
return; // filter urls not parsed
} Utf8 mark = Mark.UPDATEDB_MARK.checkMark(page);
if (!batchId.equals(REINDEX)) {
if (!NutchJob.shouldProcess(mark, batchId)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Skipping " + TableUtil.unreverseUrl(key) + "; different batch id (" + mark + ")");
}
return;
}
} NutchDocument doc = indexUtil.index(key, page);
if (doc == null) {
return;
}
if (mark != null) {
Mark.INDEX_MARK.putMark(page, Mark.UPDATEDB_MARK.checkMark(page));
store.put(key, page);
}
context.write(key, doc);
}
}

3、调用context.write()
由于  job.setOutputFormatClass(IndexerOutputFormat.class);

所以写入index??



(三)public class IndexUtil 
1、调用index()方法
  public NutchDocument index(String key, WebPage page) {
NutchDocument doc = new NutchDocument();
doc.add("id", key);
doc.add("digest", StringUtil.toHexString(page.getSignature()));
if (page.getBatchId() != null) {
doc.add("batchId", page.getBatchId().toString());
} String url = TableUtil.unreverseUrl(key); if (LOG.isDebugEnabled()) {
LOG.debug("Indexing URL: " + url);
} try {
doc = filters.filter(doc, url, page);
} catch (IndexingException e) {
LOG.warn("Error indexing "+key+": "+e);
return null;
} // skip documents discarded by indexing filters
if (doc == null) return null; float boost = 1.0f;
// run scoring filters
try {
boost = scoringFilters.indexerScore(url, doc, page, boost);
} catch (final ScoringFilterException e) {
LOG.warn("Error calculating score " + key + ": " + e);
return null;
} doc.setScore(boost);
// store boost for use by explain and dedup
doc.add("boost", Float.toString(boost)); return doc;
}

三、plugin中的字段索引
1、关于basic字段的索引在public class BasicIndexingFilter implements IndexingFilter 中

【Nutch2.2.1源代码分析之5】索引的基本流程的更多相关文章

  1. 【Nutch2.2.1源代码分析之4】Nutch加载配置文件的方法

    小结: (1)在nutch中,一般通过ToolRunner来运行hadoop job,此方法可以方便的通过ToolRunner.run(Configuration conf,Tool tool,Str ...

  2. 【原创】k8s源代码分析-----kubelet(1)主要流程

    本人空间链接http://user.qzone.qq.com/29185807/blog/1460015727 源代码为k8s v1.1.1稳定版本号 kubelet代码比較复杂.主要是由于其担负的任 ...

  3. LIRe 源代码分析 4:建立索引(DocumentBuilder)[以颜色布局为例]

    ===================================================== LIRe源代码分析系列文章列表: LIRe 源代码分析 1:整体结构 LIRe 源代码分析 ...

  4. 转:SDL2源代码分析

    1:初始化(SDL_Init()) SDL简介 有关SDL的简介在<最简单的视音频播放示例7:SDL2播放RGB/YUV>以及<最简单的视音频播放示例9:SDL2播放PCM>中 ...

  5. Hadoop源代码分析

    http://wenku.baidu.com/link?url=R-QoZXhc918qoO0BX6eXI9_uPU75whF62vFFUBIR-7c5XAYUVxDRX5Rs6QZR9hrBnUdM ...

  6. Spark SQL 源代码分析之 In-Memory Columnar Storage 之 in-memory query

    /** Spark SQL源代码分析系列文章*/ 前面讲到了Spark SQL In-Memory Columnar Storage的存储结构是基于列存储的. 那么基于以上存储结构,我们查询cache ...

  7. 新秀nginx源代码分析数据结构篇(四)红黑树ngx_rbtree_t

    新秀nginx源代码分析数据结构篇(四)红黑树ngx_rbtree_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csd ...

  8. HBase源代码分析之HRegion上MemStore的flsuh流程(一)

    了解HBase架构的用户应该知道,HBase是一种基于LSM模型的分布式数据库.LSM的全称是Log-Structured Merge-Trees.即日志-结构化合并-树. 相比于Oracle普通索引 ...

  9. SDL2源代码分析3:渲染器(SDL_Renderer)

    ===================================================== SDL源代码分析系列文章列表: SDL2源代码分析1:初始化(SDL_Init()) SDL ...

随机推荐

  1. Java学习笔记--NIO

    参考资料:http://ifeve.com/buffers/ BIO/NIO/AIO的区别联系 http://stevex.blog.51cto.com/4300375/1284437http://w ...

  2. org/hamcrest/SelfDescribing

    今天在Idea下使用JUtil的时候,运行@Test,报错:org/hamcrest/SelfDescribing 解决办法: (1)换成junit-4.8.jar (2)junit-4.11.jar ...

  3. 单线程Singleton模式的几个要点

    1.Singleton模式中的实例构造器可以设置为protected以允许子类派生.2.Singleton模式一般不要支持ICIoneable接口,因为这可能会导致多个对象实例,与Singleton模 ...

  4. MVC3路由设置访问后缀 html jsp

     C# Code  12345678910111213141516171819202122232425262728293031323334353637383940414243444546   publ ...

  5. 程序错误[C/C++]

    对于初学者而言,一般意义上,程序错误可以分为两类,逻辑错误和非逻辑错误.前者是指,程序可以通过编译或链接但运行时不符合预期结果,后者是程序不能通过编译或链接. 乍一看这样的分类非常清楚.不过,当引入语 ...

  6. 学习phpcms模板方法:

    1.改官方模板,读里面的代码,改改它,看看有什么变化,如果不明白,去官方论 坛.查手册.专业人士还可以看数据库.2.复制实例代码,整理笔记,到实战的时候,就直接复制,改改参数即可.

  7. SQL - 删掉数据库

    ALTER DATABASE [DB_NAME]SET OFFLINEWITH ROLLBACK IMMEDIATEGODROP DATABASE [DB_NAME]GO

  8. css中的7中属性选择器

    在CSS的选择符中有七个属性选择符.它们分别是: 1.E[att] 选择具有att属性的E元素. 2.E[att="val"] 选择具有att属性且属性值等于val的E元素. 3. ...

  9. Performance Tuning guide 翻译 || 前言

    CSDN 对格式支持比較弱,能够到http://user.qzone.qq.com/88285879/blog/1399382878 看一致的内容. 前言Preface 包含例如以下几个小节 l Au ...

  10. 辛星解读mysql的用户管理

    可能做开发的多半不太关注这方面,可是要说到做运维.那就不能不关注了.由于我们都知道,root的权限太大了.不是随便能用的.我们平时最好用一些比較低的权限的用户.这样会让我们的安全性大大提高,也能防止我 ...