The means justifies the ends
ちょっと思うところがあって、このブログの記事を全文検索エンジンである Hyper Estraier のインデックスに放り込んで、キーワード抽出してみたり、関連記事検索をしてみたり、という実験をごそごそやっています。
Hyper Estraier には、ファイルシステム上のテキストや HTML などのファイルを一括でインデックスに登録するツールは付属しているのですが、ご存じの通りここで使っているブログシステムの Nucleus は、記事データをファイルではなく MySQL などのデータベース上に保存しているので、付属のツールは使えません。
Web を検索してみたら、Livedoor の中の人が同じようなことを行ったメモ(Hyper Estraier で検索)を公開してくれていて、それをほんのちょっとだけ書き換えたら簡単にできちゃいましたので、そのコードをお裾分け。
#!/usr/local/bin/perl
use strict;use DBI;
use Readonly;
use Encode;
use DateTime::Format::MySQL;
Readonly my $datasources => [ 'dbi:mysql:nucleus', 'ユーザー名', 'パスワード' ];
Readonly my $base_dir => "/tmp";
Readonly my $node_path => "$base_dir/casket/";
Readonly my $ESTCMD => "/usr/local/bin/estcmd";
Readonly my $DRAFT_FORMAT => <<'END_DRAFT'
@uri=http://www.higuchi.com/item/%d
@title=%s
@cdata=%s+09:00
%s
%s
END_DRAFT
;
## create node
system( ESTCMD, "create", $node_path )
unless -d $node_path;
## indexing
my $entries = get_entries();
for my $entry (@$entries) {
do_estcmd("put", {
entry => $entry,
opts => [qw(-cl)],
}, \&_mk_draft);
}
do_estcmd("extkeys", { opts => [qw(-um)] });
sub build_estcmd {
my ( $subcmd, $opts ) = @_;
my $cmd = join( ' ', $ESTCMD, $subcmd, @$opts, $node_path );
return $cmd;
}
sub do_estcmd {
my ($subcmd, $params, $callback) = @_;
my $command = build_estcmd($subcmd, $params->{opts});
open( CMD, "| $command" ) || die $!;
print CMD $callback->($params->{entry}) if $callback;
close( CMD );
}
sub _mk_draft {
my $entry = shift;
my $dt = DateTime::Format::MySQL->parse_datetime( $entry->{itime} );
my $input = sprintf( $DRAFT_FORMAT,
$entry->{inumber}, $entry->{ititle}, $dt, $entry->{ibody}, $entry->{imore} );
return $input;
}
sub get_entries {
my $dbh = DBI->connect( @{$datasources},
{ RootClass => "DBIx::ContextualFetch" } )
or die $DBI::errstr;
$dbh->do("set names utf8");
my $sql = qq{SELECT * FROM nucleus_item WHERE idraft=0};
my $sth = $dbh->prepare($sql);
$sth->execute;
my $entries = $sth->fetchall_hash;
$sth->finish;
$dbh->disconnect;
return $entries;
}
1;
__END__