リスト項目と選択肢

作成日:2006-07-30
最終更新日:

1. 検索されないページ

Namazu は検索システムとして、非常によくできている。 しかし、次に挙げる問題点を発見した。 リスト項目を表す li タグの前や、選択肢を表す option タグの前で、 単語を区切らない。このため、 リスト項目や選択肢にある単語をキーワードとして検索しても、 該当するキーワードがあるファイルが検索結果に表示されない。

上の問題点を見付けたのは、テストによってではない。 Namazu のデータベースがあるディレクトリに、NMZ.w ファイルがある。 これを見ていると、長過ぎる単語がある。たとえば、 ハイビスカスから始まり、バコパ、ハツユキカズラ、 などの名前がずっと連なっている「単語」がある。そのほか、 バッハ、ヘンデルから始まり作曲家が連なっている単語などがある。

調べてみたら、ハイビスカス...は、 li タグを使っているページから、 バッハ...は、 option タグを使っているページから抽出されたことがわかった。 その他、td タグを使っているページからも、同様の例があった。

なお、NMZ.w は、抽出したキーワードを1行1語の形式で収めている、 テキストファイルである。1行が70バイトを越える語を抽出するには、 例えば ruby では次のようにする。

$ruby -n -e 'print if $_.length > 70' NMZ.w

$ruby -Ke -n -e 'print if $_.length > 70' NMZ.w

また、最も長い単語10個を表示するには次のようにする。私は Ruby も使うが、 awk も好きだ。awk 偏愛者なのだろう。

$awk '{print length($1), $1}' NMZ.w | sort -nr | head

2. いいかげんな対症療法

原因はよくわからない。対症療法は次の通りである。 mknmz 実施時に使う設定ファイルが、$HOME/.mknmz であるとする。 このファイルの %Weight ハッシュを指定するところで、次の行を加える。

'li'      => 1, 
'option'  => 1,
'td'      => 1,

これで、<li> </li> などで挟まれた言葉を、 登録することができる。ただし、 従来どおり長い言葉も同時に登録されてしまう。 根本原因は何か、長い言葉が登録されないようにするにはどうすればよいか、 これからの課題である。

3. 改行除去の抑制による対策

しばらく上記問題を調べていて、ようやく解決方法を見付けた。 Namazu のソースコードのshare/namazu/pl/gfilter.pl の white_space_adjust_filer 関数のうち次の2行を、 次のようにコメントアウトする(行頭に#をつける)。
# $$text =~ s/^ +//gm;
# $$text =~ s/ +$//gm;
この意味を解説する。

<li> </li> などのタグは、 わかち書きの前処理でスペースに変換される。 その後、上記の処理で、改行の前後のスペースが取り除かれる。 そうすると、わかち書きをスペースで区切った意味がなくなる。 そこで上記処理をコメントアウトし、抑制することで、 タグによる分かち書きが実施されて、所望の結果が得られる。 (2006-11-26)

4. 改行による対策

上記対策は、副作用がある。 分かれてほしくない単語でも、 途中で改行されていると改行された前後で別の単語とみなされてしまう。 そこで別の対策を示す。ただし、十分なテストを行っていない。 思わぬ副作用があるかもしれない。ご自分の責任で実施してほしい。

上記コメントアウトは元に戻すことを前提に、次の2箇所でソースコードを変更する。

1. share/namazu/filter/html.pl の element_space 関数を次のように変更する。

#    $_[0] =~ /^($conf::NON_SEPARATION_ELEMENTS)$/io ? "" : " "; # コメントアウト
    $_[0] =~ /^($conf::NON_SEPARATION_ELEMENTS)$/io ? "" : "\x00" ; # 変更

2. share/namazu/pl/gfilter.pl の white_space_adjust_filter 関数の末尾を 次のように変更する。

#    $$text =~ tr/\x00-\x09\x0b-\x1f/  /;       # コメントアウト
    $$text =~ tr/\x00-\x09\x0b-\x1f/\n/;        # 変更

この意味は次の通りである。まず最初の element_space の変更について説明する。 元の文は、HTML タグの中で、単語を分離させる種類と分離させない種類を分けて、 前者は区切り文字としてスペースで置き換えるという意味である。 ここで、スペース文字に置き換えてしまうと、前項で述べたとおり改行処理で消えてしまうことになる。 そこで、改行処理で消えず、また何の意味ももたない区切り記号として、コントロールコードを用いた。 つまり、\x00-\x09 または \x0b-\x1f の一つであれば、どれでもよい。

次に、white_space_adjust_filter について説明する。 この行はコントロール文字を除去する処理であるが、 ここで単に除去してしまっては区切り記号の効果を失ってしまう。 そこで、コントロールコードを区切りとして使うために改行に置換している。 他のスペース系でもよいが、<li>がhtmlのブラウザで改行されて見えるので、 視覚的な関連性から改行を選んだ。

以上の処理は Windows XP 上の Namazu 2.0.18 で試し、意図した結果を得た。 念を押すが、テストは十分ではないので、副作用により問題が発生するかもしれない。 ご自分の責任で実施してほしい。

まりんきょ学問所全文検索システム Namazu > リスト項目と選択肢


MARUYAMA Satosi