nutch中如何實(shí)現(xiàn)索引去重

這篇文章主要介紹nutch中如何實(shí)現(xiàn)索引去重,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

成都創(chuàng)新互聯(lián)公司來(lái)電聯(lián)系:18980820575,為您提供成都網(wǎng)站建設(shè)網(wǎng)頁(yè)設(shè)計(jì)及定制高端網(wǎng)站建設(shè)服務(wù),成都創(chuàng)新互聯(lián)公司網(wǎng)頁(yè)制作領(lǐng)域10年,包括柔性防護(hù)網(wǎng)等多個(gè)行業(yè)擁有豐富的網(wǎng)站營(yíng)銷經(jīng)驗(yàn),選擇成都創(chuàng)新互聯(lián)公司,為企業(yè)保駕護(hù)航。

一、主程序調(diào)用

SolrDeleteDuplicates dedup = new SolrDeleteDuplicates();

dedup.setConf(getConf());

dedup.dedup(solrUrl);

二、job任務(wù)配置

JobConf job = new NutchJob(getConf());

job.setInputFormat(SolrInputFormat.class);

job.setMapperClass(IdentityMapper.class);

job.setMapOutputKeyClass(Text.class);

job.setMapOutputValueClass(SolrRecord.class);

job.setReducerClass(SolrDeleteDuplicates.class);

job.setOutputFormat(NullOutputFormat.class);

JobClient.runJob(job);

三、Map、reduce任務(wù)的輸入和輸出

Map任務(wù)輸入、輸出

public void map(

K key, V val,

      OutputCollector<K, V> output

reduce任務(wù)輸入、輸出

輸入:Text/Iterator<SolrRecord>

輸出:Text/SolrRecord

public void reduce(

Text key, Iterator<SolrRecord> values,

      OutputCollector<Text, SolrRecord> output

四、job任務(wù)輸入類SolrInputFormat

getSplits方法將所有的文檔按照數(shù)量平均分片

getRecordReader方法中利用solrserver查詢了當(dāng)前分片包含的所有doc記錄,solrrecord返回了的當(dāng)前的RecordReader<Text, SolrRecord>記錄(RecordReader是一個(gè)全局的變量),并且有獲取下一個(gè)方法。

(1)、SolrInputFormat的getSplits方法

1、根據(jù)job對(duì)象的參數(shù),獲取solrserver對(duì)象。

2、構(gòu)建并執(zhí)行查詢(查詢參數(shù):[*:*、id、setRow(1)] ),獲取響應(yīng)對(duì)象

3、根據(jù)響應(yīng)對(duì)象獲取索引總數(shù),除以分片數(shù),得到每一片分配多少個(gè)索引

4、根據(jù)分片數(shù)創(chuàng)建 SolrInputSplit數(shù)組對(duì)象,

5、根據(jù)solr輸入分片的開始和結(jié)束位置,實(shí)例化SolrInputSplit對(duì)象

    public InputSplit[] getSplits(JobConf job, int numSplits) throws IOException {

      SolrServer solr = SolrUtils.getCommonsHttpSolrServer(job);

      final SolrQuery solrQuery = new SolrQuery(SOLR_GET_ALL_QUERY);

      solrQuery.setFields(SolrConstants.ID_FIELD);

      solrQuery.setRows(1);

      QueryResponse response;

      try {

        response = solr.query(solrQuery);

      } catch (final SolrServerException e) {

        throw new IOException(e);

      }

      int numResults = (int)response.getResults().getNumFound();

      int numDocsPerSplit = (numResults / numSplits); 

      int currentDoc = 0;

      SolrInputSplit[] splits = new SolrInputSplit[numSplits];

      for (int i = 0; i < numSplits - 1; i++) {

        splits[i] = new SolrInputSplit(currentDoc, numDocsPerSplit);

        currentDoc += numDocsPerSplit;

      }

      splits[splits.length - 1] = new SolrInputSplit(currentDoc, numResults - currentDoc);

      return splits;

    }

(2)、SolrInputFormat的getRecordReader()方法

1、獲取solrserver對(duì)象

2、將傳入的split參數(shù),強(qiáng)轉(zhuǎn)成SolrInputSplit對(duì)象,并獲取這個(gè)分片的文檔總數(shù)

3、構(gòu)建查詢對(duì)象,執(zhí)行查詢(參數(shù)[*:*,id,boost,tstamp,digest, SolrInputSplit中的開始位置,文檔總數(shù) ])。

4、根據(jù)響應(yīng)對(duì)象,獲取結(jié)果集

5、對(duì)匿名內(nèi)部?jī)?nèi)RecordReader做了實(shí)現(xiàn),并且返回

    public RecordReader<Text, SolrRecord> getRecordReader(final InputSplit split,

        final JobConf job, 

        Reporter reporter)

        throws IOException {

//1、獲取solrserver對(duì)象

      SolrServer solr = SolrUtils.getCommonsHttpSolrServer(job);

//2、將傳入的split參數(shù),強(qiáng)轉(zhuǎn)成SolrInputSplit對(duì)象,并獲取這個(gè)分片的文檔總數(shù)

SolrInputSplit solrSplit = (SolrInputSplit) split;

      final int numDocs = solrSplit.getNumDocs();

      

//3、構(gòu)建查詢對(duì)象,執(zhí)行查詢(參數(shù)[*:*,id,boost,tstamp,digest,

SolrInputSplit中的開始位置,文檔總數(shù)

])

      SolrQuery solrQuery = new SolrQuery(SOLR_GET_ALL_QUERY);

      solrQuery.setFields(SolrConstants.ID_FIELD, SolrConstants.BOOST_FIELD,

                          SolrConstants.TIMESTAMP_FIELD,

                          SolrConstants.DIGEST_FIELD);

      solrQuery.setStart(solrSplit.getDocBegin());

      solrQuery.setRows(numDocs);

      QueryResponse response;

      

try {

        response = solr.query(solrQuery);

      } catch (final SolrServerException e) {

        throw new IOException(e);

      }

//4、根據(jù)響應(yīng)對(duì)象,獲取結(jié)果集

      final SolrDocumentList solrDocs = response.getResults();

      return new RecordReader<Text, SolrRecord>() {

//當(dāng)前的文檔

        private int currentDoc = 0;

        public void close() throws IOException { }

        public Text createKey() {

          return new Text();

        }

        public SolrRecord createValue() {

          return new SolrRecord();

        }

//獲取當(dāng)前的指針

        public long getPos() throws IOException {

          return currentDoc;

        }

//獲取進(jìn)度

        public float getProgress() throws IOException {

          return currentDoc / (float) numDocs;

        }

//獲取下一個(gè)

        public boolean next(Text key, SolrRecord value) throws IOException {

          if (currentDoc >= numDocs) {

            return false;

          }

//

          SolrDocument doc = solrDocs.get(currentDoc);

//獲取摘要

          String digest = (String) doc.getFieldValue(SolrConstants.DIGEST_FIELD);

//把摘要作為key

          key.set(digest);

//value(SolrRecord)

//賦值:通過(guò)doc給solrrecord的id,tstamp,boost 3個(gè)字段賦值

          value.readSolrDocument(doc);

//指針加自增1

          currentDoc++;

          return true;

        }    

      };

    }

  

五、map()方法和reduce()方法中的實(shí)現(xiàn)

(1)、map任務(wù)

(2)、reduce任務(wù)

去重邏輯:

reduce任務(wù)會(huì)遍歷每一個(gè)record,并執(zhí)行reduce()方法中的代碼

reduce()方法中,會(huì)遍歷處于當(dāng)前文檔之后的所有文檔,如果分值和時(shí)間都比當(dāng)前的小,會(huì)調(diào)用solrj刪除這個(gè)文檔,如果比當(dāng)前的大,會(huì)刪除當(dāng)前的,并把當(dāng)前的替換成這個(gè)大的。

  public void reduce(Text key, Iterator<SolrRecord> values,

      OutputCollector<Text, SolrRecord> output, Reporter reporter)

  throws IOException {

     //1、下一個(gè)SolrRecord對(duì)象

    SolrRecord recordToKeep = new SolrRecord(values.next());

//2、遍歷了SolrRecord

    while (values.hasNext()) {

//

      SolrRecord solrRecord = values.next();

//boost、tstamp參與比較

//如果當(dāng)前的分值, 比保持的分支高,并且時(shí)間比保持的新,就根據(jù)id刪除這條索引,

      if (solrRecord.getBoost() > recordToKeep.getBoost() ||

          (solrRecord.getBoost() == recordToKeep.getBoost() && 

              solrRecord.getTstamp() > recordToKeep.getTstamp())) {

        updateRequest.deleteById(recordToKeep.id);

        recordToKeep = new SolrRecord(solrRecord);

      } else {

        updateRequest.deleteById(solrRecord.id);

      }

      numDeletes++;

      reporter.incrCounter("SolrDedupStatus", "Deleted documents", 1);

      if (numDeletes >= NUM_MAX_DELETE_REQUEST) {

        try {

          LOG.info("SolrDeleteDuplicates: deleting " + numDeletes + " duplicates");

          updateRequest.process(solr);

        } catch (SolrServerException e) {

          throw new IOException(e);

        }

        updateRequest = new UpdateRequest();

        numDeletes = 0;

      }

    }

  }

六、關(guān)于digest

doc中的digest字段,是在IndexerMapReduce類中的reduce方法中加入的

// add digest, used by dedup

doc.add("digest", metadata.get(Nutch.SIGNATURE_KEY));

Metadata中包含了一個(gè)HashMap

final Metadata metadata = parseData.getContentMeta();

以上是“nutch中如何實(shí)現(xiàn)索引去重”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

文章名稱:nutch中如何實(shí)現(xiàn)索引去重
本文來(lái)源:http://muchs.cn/article10/jojogo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站軟件開發(fā)、標(biāo)簽優(yōu)化響應(yīng)式網(wǎng)站、建站公司、移動(dòng)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)