ヴォルフロッシュ

Blog

Published on

RSS

ヴォルフロッシュ v4 -サイト内検索

サイトリニューアル記念内容大公開、最終回は新しくお目見えしたサイト内検索についてです。

だんだん内容がマニアックになってきました。ウェブデザインおよびプログラミングに興味がない人にはなんのこっちゃな内容だと思うので、そういう方は適当に読み飛ばして下さい。まぁ、雰囲気モノとして読んで見るのも良いでしょう。コンナカンジデス、うぇぶさいとセイサク。いずれにせよ、このサイト専用の検索システム、汎用性にも欠けるのでそんな具体的なソースコードについては書きません。


とはいえもちろんシステムと作り方の話をします。

サイト内検索はサイト内検索、名前の通り当サイトヴォルフロッシュ内の全ページを検索できるweb検索システムです。ここに書くぐらいなのでそのとおり、この検索システムも1024が自分でいちから開発しています。自分でテンプレートシステムを作り自分でBlogシステムを作ったこのサイトを検索できるのは自分で書く検索システムくらいなもんです。なんて、本当は他にもやりようはあるのですが、あまりスマートじゃないしせっかくなんだから自分で作りたい。くどいですが、ここはそういう趣旨のサイトなんです。

(ちなみに以前はmsearchというPerlスクリプトで書かれた検索エンジンを使ってました)

中身としては、基本的には以前からあったBlog内検索と同じgrep式です。実際このBlog内検索を拡張して、このサイト内検索を作りました。ただ、Blog部分とそれ以外の一般ページではデータの保存の仕方が違うので、そこを今回新しく書いたわけです。Blog内検索について詳しく知りたい人は過去の記事を読んで下さい。

前提条件

どういうことかというと、このBlogページはそれぞれ、実体としてそこにファイルがあるわけではありません。たとえばこの記事はwolfrosch.com/text/2011/06/25というURLが割り振られていますが、実際に、text/2011/06/というディレクトリに25.phpや25.htmlなどといったファイルがあるわけではない。text/直下にあるプログラムで自動的にページを生成して、この見かけのURLと共にクライアントにページを投げているわけです。まぁ、一般的にブログというのはどれもそんなもんです。本文は別の場所に一括して置いています(といっても、このBlogは私のこだわりで、データベースではなくテキストファイルでデータを管理してます

一方、Blog以外の一般ページ(面倒なので以下 "一般ページ" または "ページ検索" と呼びます)はそれぞれ実体がある。URLで見えるままディレクトリがサーバに掘ってあって、それぞれphpファイルが置いてある。そこに本文をべた書きして(このBlogでも一般ページでも、私はいつもHTMLソースをテキストエディタで直接書いてます。今も。)、そのファイルの中で、テンプレートとなるスクリプトファイルや関数を呼び出して、共通部分を自動生成しています。

なので、以前作ったBlog検索にそのまま他のページを投げるわけにはいかない。だからこそ以前Blog検索を作った時はBlog内しか検索できないのをひとまず作ったわけですが。

まぁとは言っても、実際に検索を回したり、それを整えて表示したりというページ検索の基本部分は共通しているので、いちから全部書き直さなくてもいままでのBlog検索スクリプトが流用できるはずなのです。

実際にやったこと

引越し

もともとBlog内検索だったのでBlogのディレクトリにありそこに組み込まれていたモノをSearch/ディレクトリに移してして1つのコンテンツという扱いにします。まぁここはサクッと。

インデックス生成

さて、今回はサイト内の全ページが検索対象なわけですが、それにしても検索をかけるファイルだけを読みたい。BlogはもともともBlogの時点で記事をリスト化したCSVがあったので、それを読んで順番にデータを拾って検索してたのですが、一般ページはファイルがサイトのあちこちに散らばってるし、そこには本文データじゃないスクリプトだの画像だの設定ファイルだのもしくはディレクトリだのも共存してる。そこから実際に検索対象になるファイルだけを拾わないといけない。さてどうする。ちなみにこのサイトは現時点で一般ページは100ページほどあります。

そんなPVのあるサイトでもないので、検索キューを受けるたびに毎回ディレクトリを読みにいってページ探しても良かったのですが、結構違う処理なんでそこは切り分けました。どうせ一覧を配列で持たないと検索回せないし。ということでまず検索対象となるページのパスやタイトルを収納したテキストインデックスファイルを生成するスクリプトを書きました。これを作っておいて検索する時はそのリストの先のファイルを片っ端から読みにいくわけです。インデックス型とgrep型の中間みたいなもんで、まぁそんな奇抜な方法ではないはず。それにこれなら「インデックス-本文ファイル」という構造がBlogと一緒になるのでその後の処理がやりやすい。

リスト化自体は以外と簡単でした。そもそも現在公開してるトップレベルのコンテンツ(AboutとかArchitectureとかね)のリストはテンプレートシステムが配列で持ってるし、それに私は、コンテンツファイル以外のファイル(設定ファイルとか)は頭をアンダースコア(_)から始めるという気の利いたmyルールを作って実践していたのだ。えらいなぁ。おかげで検索スクリプト用に読む込むディレクトリやファイルを具体的に指定したりは今回せずに済みました。ので各コンテンツディレクトリを2階層くらい読みにいって、対象ファイルを集めるだけ。ページのタイトルは各ページの先頭で関数に入れてるので、そこはファイルを開いて最初だけ読む。そしてインデックスのファイルを生成して吐く。これを1回すれば、検索をかけるたびにはファイルを探したりタイトル拾ったりせずに済むわけです。もちろん更新してページを足したりしたらインデックスも更新はしないといけませんが。

関数化

次に、Blog検索から流用できそうなところを切り出します。今まではBlog記事を検索するだけだったのでメイン処理で直接書いてたような手続きを、適宜関数化して抜き出すわけです。逆に言うと、本当にそのまま使えるところはそのままでも良い。たとえば検索キーワードの入力欄。エラー表示とか。そうじゃなくて同じような作業をさせたいけどこのまま投げるわけには...みたいな、具体的に言うと、メインの検索を回すループと結果表示のループ。それぞれコアの部分ですね。あとは分岐させやすいようにぞれぞれのインデックスを配列に読み込む部分も関数に切り出しました。これを関数化して、まずその状態で従来のBlog検索ができるようにする。それができるようになったら、次は投げるデータによってif文で適宜切り替えたりして一般ページの検索もできるようにする。

統合と両立

ここまでできたらやっと最後に、インターフェイスレベルからBlog検索とページ検索が切り替えられるようにしたり、もしくは両方を串刺しで検索したいときに2種を両方回して結果も統合して続けて出るようにします。Blog検索だったらオプションが指定できるようにしたりもこの辺でやりました。ここはやはりjavascript噛ませたりね。

ということで、Blog記事検索とBlog以外のページの検索で検索範囲が切り替えられるようになっているのは、実はこのような開発時点での事情の名残です。どうせ内部で切り替えて違う処理をしてるのだから、それぞれ選択できるようにしよう、と。

それに元のBlog内検索ではタグや投稿日でも絞り込みができるようなってたので、どうせならそれも残したかった。一般ページにはタグとかないからね。投稿日も。

ページ分割

ついでに今回、結果表示のページ分けもしました。以前は手を抜いて、検索結果が100件だろうと200件だろうと、1ページにずらずら表示させてたのですが、10件毎にページ分けされるようにしました。だからどうってほどでもないですが、そういうのも実装するとなると手がかかるもので。今回腰を上げました。まぁ、pageというクエリをおいて、結果表示のforループのスタートと終わりを指定してるだけです。あとはそのページのナビゲーションを作ったり色々。

オブジェクト指向

と、ここまで旧式の手続き型で作っていたのですが、サイトのテンプレートとBlogをオブジェクト指向風味に書き換えたので、ここにきて検索システムもそれに合わせて修正。せっかくきれいなコードが書けたのになぁなんて思いながら、手続き型のv1は結局一度も日の目を見ないまま解体されてしまったのです。といっても仕組みとかコアはそんなに変わらないのですが。

完成

で完成したのがこのサイト内検索。細かい仕様は使い方を見て内部処理でも想像してください。

いずれにせよかなーり満足しています。or検索とかGoogleみたいに同じ言葉の違う表記も拾うとか重み付けして重要そうなのが上にくるとか、できないことも多いけど、基本は事足りるぜ。2つの違うシステムで動いてるコンテンツを串刺して検索できるってのはなかなか良いのではないかと思います。

それにね、テンプレート型の一般ページと、それと別駆動で動いてるBlogと、それを串刺し検索するサイト内検索の3つが、同じテンプレートスクリプトで共通部分を一発生成できるって地味に便利ですごいのよ。サイト持ってる人なら想像できると思います。ここは自画自賛させてください。

まぁせっかく作ったので、いろいろ検索してみてあげてください。うちのサイト諸々合わせても600ページ越えですからね、なんか探してるなら検索した方が早いよ。そしてバグが見つかったら私に連絡して下さい。デバッグよろしく。

ちなみにこの検索システム、私が自分でサイトに手を入れるときに大いに使っているので、一番重宝しているのは私自身かもしれません。

最後に

数日に渡り、長々書きましたが、ウェブサイト制作自体について書くのもこのサイトのコンテンツの1つだし、同じようなことをしている・したい人と情報共有できたらと思い書きました。以上です。質問があれば答えます。

Comment

この記事へのコメント受付は終了しました。