nutch 0.9でクロールした結果をクロールした日付順にソートしたい

nutch 0.9のbin/nutchコマンドやorg.apache.nutch.crawl.Crawlクラスのmainメソッド実行によって、作成されたDBでは、tstampフィールドに対してインデクスが付けられない。

デフォルト設定のクロールのtstampフィールド

  1. インデクスなし
  2. トーカナイズなし

フィールドでソート処理を行うためには、インデクスありでトーカナイズがされない状態である必要がある。

tstampフィールドでソートを行うために必要な状態

  1. インデクスあり
  2. トーカナイズなし

tstampフィールドの状態は、Lukeからも確認できる。

デフォルトの状態でクロールを実行してもインデクスがつかないtstampフィールドにインデックスを付けるには、

org.apache.nutch.indexer.basic.BasicIndexingFilter

を修正する必要がある。
BasicIndexingFilterクラスの100行目付近

doc.add(new Field("tstamp",
DateTools.timeToString(datum.getFetchTime(), DateTools.Resolution.MILLISECOND),
Field.Store.YES, Field.Index.NO));

となっているところを以下のように修正する

doc.add(new Field("tstamp",
DateTools.timeToString(datum.getFetchTime(), DateTools.Resolution.MILLISECOND),
Field.Store.YES, Field.Index.UN_TOKENIZED));

修正したBasicIndexingFilter.javaファイルをコンパイルして出来たBasicIndexingFilter.classクラスファイルを、含むindex-basic.jarライブラリを作りなおせばOK。

クロールを再度実行し、LUKEでインデクスの中身を見ると、tstampフィールドにインデクスが付けられているのがわかる。


プログラムからtstampフィールドでソートされたHitsオブジェクトを得るには、以下のようにtstampフィールドを指定して作成したSortオブジェクトをsearchメソッドの引数に渡せばいい。

FSDirectory indexDir = FSDirectory.getDirectory( "C:\\crawl_v09_20090908_2\\index", false );
IndexSearcher indexSearcher = new IndexSearcher( indexDir );
SortField sortField = new SortField("tstamp", SortField.STRING);
Sort sort = new Sort(sortField);
Hits hits = indexSearcher.search( new MatchAllDocsQuery(), sort );

ちなみに、以下のようにしても正しくソートされなかった。

Hits hits = indexSearcher.search( new MatchAllDocsQuery(), new Sort("tstamp", true) );

ソートを実現するにあたり、参考にさせていただいたサイトは、以下になります。
ありがとうございました!

livedoor開発日記