urlフィールドが特定の複数ドメインのもののみを取得したい
クロールしたURLが以下のようなとき
http://aaa.bb
http://ccc.dd
http://eee.ff
この2つのサイトに対してだけ検索したいときです。
しばらく悩んであとに、Lukeでインデックスの中身をのぞいているときに、ふと思った。。
urlフィールドを選んで、「show top terms >>」ボタンを押して、表示されるTextが単語区切りになっている・・・。
これじゃあ、Termkeino
tstampフィールドの値を"yyyy/MM/dd HH:mm:ss"形式で表示するには
tstampフィールドの値は、Lukeなどを使ってみると、"20090908080249515"のような17桁の数字になっている。
この17桁の数値は、Hitオブジェクトのgetメソッドを使って取得することができるので、これを整形できればよい。
ということで、17桁の数値のもとをたどると。。
BasicIndexingFilerクラスの100行目
doc.add(new Field("tstamp",
DateTools.timeToString(datum.getFetchTime(), DateTools.Resolution.MILLISECOND),
Field.Store.YES, Field.Index.NO));
getFetchTimeメソッドを追ってみると、
public long getFetchTime() { return fetchTime; }
fetchTimeを追ってみると、
private long fetchTime = System.currentTimeMillis();
tstampフィールドの値は、System.currentTimeMilliis()の値だということがわかる。
さて、tstampフィールドの値をHitオブジェクトのgetメソッドを通じて取得すると、String型に変換後の値が出力されるので、プログラムでtstampフィールドの値をフォーマットするには、もう少し工夫する必要があった。
つまり、String型からDate型に戻してあげる作業が。。うーん。。ほふく前進だ。
Date tstamp = DateTools.stringToDate(hit.get("tstamp"));
nutch 0.9でクロールした結果をクロールした日付順にソートしたい
nutch 0.9のbin/nutchコマンドやorg.apache.nutch.crawl.Crawlクラスのmainメソッド実行によって、作成されたDBでは、tstampフィールドに対してインデクスが付けられない。
デフォルト設定のクロールのtstampフィールド
- インデクスなし
- トーカナイズなし
フィールドでソート処理を行うためには、インデクスありでトーカナイズがされない状態である必要がある。
tstampフィールドでソートを行うために必要な状態
- インデクスあり
- トーカナイズなし
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) );
ソートを実現するにあたり、参考にさせていただいたサイトは、以下になります。
ありがとうございました!
bin/nutchコマンドを使わずにクロールを実行する
org.apache.nutch.crawl.Crawlクラスのmainメソッドを呼び出すことで、クロールを実行することができる。
Eclipseから実行する場合、mainメソッドの引数渡すパラメータは、デバグ設定の画面から指定できる。
が、ここで問題が!
nutch 0.9までは、Crawlクラスのmainメソッド実行により作成されたデータベースに対して、Lukeなどを使って、インデクスの内容を問題なく読むことが出来たのに、nutch 1.0になってからは、Lukeを使ってインデクスの内容を読めなくなってしまった。
nutch 1.0のbinディレクトリにあるnutchコマンドを実行して作成されたデータベースは、問題なくLukeを使って内容を見ることができるので、どうゆうことなんだろう?