at posts/single.html

PukiWiki の負荷軽減 (3)

先日に続いて、検索エンジン Estraier で PukiWiki のページを検索する話。 方法としては、以下の2通りが考えられる。

  • ソースそのものを検索対象とする
  • HTML に変換したものを検索対象とする

検索精度を考えると、HTML に変換したものを対象にしたほうがいいんだろうけど、キャッシュで HTML を残すように改造しないといけないので、今回は単純にソースを検索対象とする。

検索インデックスの生成

Estraier は Namazu と同じく、事前に検索インデックスを作っておく(だから、高速に検索できる)。 検索インデックスを作るためのコマンドは、こうなる。

$ estindex register -list list.txt -hsuf '*' jinroh
$ estindex relate jinroh

-list で指定するファイル(ここでは list.txt)には、検索対象となるファイル名とそのURLを記述しておく。わざわざ -list で指定するのは、PukiWiki では物理的なファイル名と URL が異なるため。例えば、 53616E64426F78.txt というファイル名は index.php?SandBox という URL にマッピングされる。

このリストファイルは、簡単なスクリプトで生成できるようにした。

#!/usr/bin/env ruby
require 'uri'

base_url = 'http://wolfbbs.halfmoon.jp/?'
Dir.glob(ARGV.shift) do |file|
  filename = File.basename(file)
  dirname = File.dirname(file)
  next if filename =~ /^3A/  # 「:」で始まるページは対象外
  url = URI.encode(filename.match(/(.*)\..*$/)[1].to_a.pack('H*0'))
  puts "#{dirname}/#{filename}\t#{base_url}#{url}"
end

検索用 CGI

検索インデックスを作ったら、次は検索用の CGI 。 基本的には Estraier についてくる estsearch.cgi を使うんだけど、そのままだとページのタイトルがファイル名のままになってしまう。 そこで、フィルタのプログラムをかまし、タイトルをデコードするようにした。

ここで、 PukiWiki の文字コードは EUC, Estraier の文字コードは UTF-8 であることに注意が必要。Uconv を使って、文字コードを変換するようにしている。

#!/usr/bin/env ruby
require 'uconv'

def decode(text)
  Uconv.euctou8(text.to_a.pack('H*0'))
end

title_reg  = %r|<a ([^>]+)>([^<]+).txt</a>|
`./estsearch.cgi`.each do |line|
  line.sub!(title_reg, "<a #{$1}>#{decode($2)}</a>")
  puts line
end

このスクリプトを search.cgi という名前にし、 estsearch.cgi と同じ場所に置いておく。ブラウザから search.cgi にアクセスすれば、検索結果のタイトルがデコードされて表示されるようになる。 本当は PukiWiki 上に設置した検索フォームからも検索できるように、もう少し細工しているけど、ここでは省略。

これで試しに設置してみたけど、やっぱり HTML に変換したものを検索対象にしたほうが精度はよさそう。そもそも、これだとページ名が検索対象にならないしさ。

関連する日記