(重要)項目整合nutch索引與查詢過程記錄

1.索引過程

  創建索引,採用的邏輯思路是:使用正則表達式,從nutch抓取流程產生的文件parse_txt中提取不同的內容,建立不同的索引域。該方法的好處是,對於論壇、新聞等不同的採集信息,可以產生不同的索引域。實例如下:

    parse_txt文檔格式(以新聞爲例):

     http://app.finance.ifeng.com/report/all.php <news><newstitle></newstitle><newstime></newstime><newssource></newssource><newsauthor></newsauthor><newstext>請選擇研究機構

東海證券長江證券宏源證券國元證券國泰君安證券東北證券海通證券廣發證券中金公司中信證券招商證券

</newstext></news>

  索引代碼處理:

  //新聞文本索引

  private NutchDocument addNewsContent(NutchDocument doc,String textString){

  String textRegex="<newstext>(.*?)</newstext>";

  Pattern p=Pattern.compile(textRegex);

  Matcher m=p.matcher(textString.replaceAll("\n", "").replaceAll("\r", ""));

  while(m.find()){

  doc.add("newscontent", m.group(1));

  }

  return doc;

  }

對於<newsauthor>、<newstitle>則用類似的方法建立相應的索引域。

在對新聞文本建立索引的過程中,出現了一個問題:newscontent索引域中的索引項是空的。出現這個現象的原因是,<newstext>標籤中的文本內容中有\n、\r等符號,這會影響正則的使用。添加了replaceAll("\n", "").replaceAll("\r", "")之後,問題就解決了。(爲何會出現這種情況,還有待研究)。

2.查詢過程

  2.1.查詢時報attributeSource。。。。的錯誤。這種錯誤一般是中文分詞的代碼中少了某些變量及其對應的操作方法,google一下,一般比較好解決。

 2.2.String index out of range -2,報這個錯誤時,就要求修改summary-basic代碼,如果你用的summary-basic插件的話。如何修改,詳見http://blog.163.com/jiaxizhu@yeah/blog/static/1574538772011111145347369/。問題還是由分詞引起的,具體原因還不太清楚,功力不夠啊!

 2.3.修改查詢源碼,實現跨索引庫查詢。

  對這段代碼的修改,主要集中在NutchBean的初始化過程中。

將以下這段代碼,進行修改;

   final Path luceneConfig = new Path(dir, "search-servers.txt");

    final Path solrConfig = new Path(dir, "solr-servers.txt");

    final Path segmentConfig = new Path(dir, "segment-servers.txt");


    if (fs.exists(luceneConfig) || fs.exists(solrConfig)) {

      searchBean = new DistributedSearchBean(conf, luceneConfig, solrConfig);

    } else {

      final Path indexDir = new Path(dir, "index");

      final Path indexesDir = new Path(dir, "indexes");

      searchBean = new LuceneSearchBean(conf, indexDir, indexesDir);

    }

   

    if (fs.exists(segmentConfig)) {

      segmentBean = new DistributedSegmentBean(conf, segmentConfig);

    } else if (fs.exists(luceneConfig)) {

      segmentBean = new DistributedSegmentBean(conf, luceneConfig);

修改後的代碼如下:

  public NutchBean(Configuration conf, Path dir) throws IOException {

    this.conf = conf;

    this.fs = FileSystem.get(this.conf);

    //TODO

    String[] dires=null;

    

    if (dir == null) {

      dir = new Path(this.conf.get("searcher.dir", "crawl"));

      //TODO

      dires=dir.toString().split(";");

    }

    //TODO

    Path[] indexCollection=new Path[dires.length];

    Path[] indexesCollection=new Path[dires.length];

    Path[] segmentsCollection=new Path[dires.length];

    Path[] linkdbCollection=new Path[dires.length];

    if(dires==null){

     System.out.println("search.dir元素中的值沒有被成功操作");

    }

    else{

    for(int i=0;i<dires.length;i++){

    dir=new Path(dires[i]);

    Path indexDir = new Path(dir, "index");

    Path indexesDir = new Path(dir, "indexes");

    Path segmentsDir=new Path(dir,"segments");

    Path linkdbDir=new Path(dir,"linkdb");

    indexCollection[i]=indexDir;

    indexesCollection[i]=indexesDir;

    segmentsCollection[i]=segmentsDir;

    linkdbCollection[i]=linkdbDir;

     }

    searchBean = new LuceneSearchBean(conf, indexCollection, indexesCollection);

    segmentBean = new FetchedSegments(conf, segmentsCollection);

    

    }

   // linkDb = new LinkDbInlinks(fs, new Path(dir, "linkdb"), conf);

    linkDb = new LinkDbInlinks(fs,linkdbCollection , conf);

    

  }

我們可以知道在初始化NutchBean的過程中,初始化了searchBean以及segmentBean以及linkDb。


相應的,各個類的代碼也要修改。

2.3.1.LuceneSearchBean

該類是用來讀取索引的。爲了滿足多索引讀取的要求,得修改其構造方法,重載一個構造方法:

 public LuceneSearchBean(Configuration conf, Path[] indexDir, Path[] indexesDir)

  throws IOException {

    this.conf = conf;

    this.fs = FileSystem.get(this.conf);

    init(indexDir, indexesDir);

  }

在這個類中,最重要的是在init方法中初始化了IndexSearcher類,該類中則初始化了Lucene的IndexSearcher,實現索引庫的查詢。

  對於IndexSearcher,它有兩個重載的構造方法,用於接收多索引路徑與單索引路徑。方法如下:

  /** Construct given a number of indexes. */

  public IndexSearcher(Path[] indexDirs, Configuration conf) throws IOException {

    IndexReader[] readers = new IndexReader[indexDirs.length];

    this.conf = conf;

    this.fs = FileSystem.get(conf);

    for (int i = 0; i < indexDirs.length; i++) {

      readers[i] = IndexReader.open(getDirectory(indexDirs[i]));

    }

    init(new MultiReader(readers), conf);

  }


  /** Construct given a single merged index. */

  public IndexSearcher(Path index,  Configuration conf)

    throws IOException {

    this.conf = conf;

    this.fs = FileSystem.get(conf);

    init(IndexReader.open(getDirectory(index)), conf);

  }

這個構造函數中的init方法調用Lucene中的IndexSearcher類的初始化方法,構建相應的對象,用來進行對索引的相關操作。
2.3.2.segmentBean
 要實現查詢,除了讀索引,還要對segments中的內容進行讀取,所以,還要配置相應的segments目錄.這是在segmentBean = new FetchedSegments(conf, segmentsCollection);中實現的。
 在這個構造函數中,修改參數,將Path segmentsDir改爲Path[] segmentsDir,同時將private final Path segmentsDir;改爲private final Path[] segmentsDir;。此外,還要修改DistributedSearch,改爲:
 //TODO
      Path[] segmentsDirs=new Path[]{segmentsDir};

      //final FetchedSegments segments = new FetchedSegments(conf, segmentsDir);
//TODO
      final FetchedSegments segments = new FetchedSegments(conf, segmentsDirs);

2.3.3.linkDb
  
linkDb = new LinkDbInlinks(fs,linkdbCollection , conf);
不太清楚lindDb這個初始化是幹嘛用的,不過根據是用來處理方向連接的事實,應該和url連接有關。
除了將path 改爲path[]之外,還要將
Path singleDirectory=directory[i];
        readers = MapFileOutputFormat.getReaders
          (fs, new Path(singleDirectory, LinkDb.CURRENT_NAME), getConf());
改爲
for(int i=0;i<directory.length;i++){
       Path singleDirectory=directory[i];
        readers = MapFileOutputFormat.getReaders
          (fs, new Path(singleDirectory, LinkDb.CURRENT_NAME), getConf());
        }
但是不太清楚得到的readers是dierctory中最後一個,還是整個directory數組中的?


2.3.4.過程中產生的錯誤
  在Myeclipse中,對項目的插件的組織是這樣的,將編譯得到的.class文件,打包成.jar文件,運行程序時,將會調用.jar中的代碼。但是,如果編譯的.class文件,仍存在於項目的SourceFolder中時,就不會運行.jar中的,默認使用處於sourceFolder中的.class文件。包括Refenced Libraries中的jar文件,如果項目中存在該.jar文件的源碼,且處於sourceFolder中,運行程序時,將不會用到.jar中的代碼,而是用到源文件中的。如果別人對某個源碼進行了修改,並打包成.jar文件,給你使用,而你項目中包含沒有修改的源碼,這時問題就出現了,程序不會運行修改的源碼,結果還是原來的樣子。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章