職場の勝手にイントラサーバでインデックスサービスによる検索サービスの機能を追加。 ちょっと手こずったのでメモ。

自宅ではディスクが勝手にカリカリいうのが嫌だし、ファイルの場所くらいは把握しているので即刻オフのインデックスサービスだけど、やっぱり本格的なイントラネットサーバ(?)では使えるようにしてみたい。ところがWindows+Namazu、Linux+Namazu+CGI の構成なんていくらでも情報があるのと対照的に、 Windows + IndexService + IIS ってのは簡単に構築できる割に情報が非常に少ない。以下インデックスサービスとIISと連携させてサーチエンジンっぽいのを構築するミッション。


まず、検索対象にする場所の指定。コンピュータの管理→サービスとアプリケーション→インデックスサービス でカタログを新規作成し、ディレクトリに指定しておく。今回はローカルドライブのみだけど、ネットワーク上も可。インデックスを作成する場所はバックアップ対象外を指定。※標準で設定されてるSystemカタログは消してもいいかも。

インデックスサービスのプロパティで「概要を作成する」オプションを有効にしておくとインデックスの要約ができるらしい。検索時にいちいち開かなくても中が分かるはずだが、いまいちわからん。

ここまでの設定をしたら、とりあえず指定したディレクトリを手動で完全スキャンしておく。後はファイルの変更時やアイドル中にIndexServiceが勝手にインデックスを更新してくれる。 (このあたりがOSの付属品というか、よくできてる。将来はWinFSとしてもっと高度で身近になるのか?) 少し放置しておけば「カタログのクエリ」で検索できるようになっているはず。


次に検索用のページを作成する。ややこしいかもと思ったけど、実際には3コのファイルを作成するだけ。 ここでは検索フォーム、クエリ定義ファイル、結果の雛形 (←勝手に命名) が必要。環境にあわせて各自で作成する。 以下は重要な部分の抜粋。YahooやGoogleとは検索方法が違うので。説明文を付け加えるとよろし。

●search.htm 検索フォーム

ただのフォームが1つあるHTML。次の.idqにPOSTする。

<html>
<body>
<!– .idq は idq.dll に関連付けする –>
<form action=”search.idq” method=”POST”>
<input type=”text” name=”CiRestriction” size=”50″ maxlength=”200″>
<input type=”submit” value=”検索”>
</form>
</body>
</html>

●search.idq クエリ定義ファイル

iniファイルに近い構文。最低限次の項目があれば動く。 実際には%windir%\system32\idq.dll に渡して解釈される。

[Query]
CiColumns=filename,size,rank,characterization,vpath,DocTitle,write
CiFlags=DEEP
CiRestriction=%CiRestriction%
# 最大件数、ページあたりの件数
CiMaxRecordsInResultSet=250
CiMaxRecordsPerPage=50
# 検索対象 / ならすべて、指定するとそれ以下のみ検索
CiScope=/docs
# 雛形 フルパスで指定すること
CiTemplate=/scr/search.htx
CiSort=rank[d]
# カタログの場所 ローカルのD:\nobakup\index.home にあると仮定
CiCatalog=D:\nobakup\index.home

●search.htx 結果の雛形

.idq で指定され、idq.dllがこれをもとに結果ページを生成するための、抽象記述。 HTML拡張ファイルという変数や簡単な制御構文が使えるもの。詳細はIndexService.exeを参照。search.idqにポストしているところだけ変えれば使える。ここに掲載したのはほぼそのまま引用だけど、実際に使ったのはもう少しかっこよくしてみた。見た目、ボタンの位置、連続して検索できるようにとか。

<HTML>
<HEAD>
<!– タイトルにヒットした文書の数を表示 –>
<%if CiMathchedRecordCount eq 0%>
<TITLE><%CiRestriction%> -条件を満たす文書はありません。</TITLE>
<%else%>
<TITLE><%CiRestriction%> – 文書<%CiFirstRecordNumber%>から文書
<%CiLastRecordNumber%>まで</TITLE>
<%endif%>
</HEAD>

<BODY>
<TD VALIGN=MIDDLE><H1><i>Indexing Service 3.0</i></H1><br>
<DIV ALIGN=center><h2>検索結果</h2></center></TD>
<DIV ALIGN=left>
<H5>

 <%if CiMatchedRecordCount eq 0%>
クエリー “<%CiRestriction%>”を満たす文書はありません
<%else%>
文書 <%CiFirstRecordNumber%> から文書 <%CiLastRecordNumber%> –全文書中
<%if CiMatchedRecordCount eq CiMaxRecordsInResultSet%>
上位
<%endif%>
<%CiMatchedRecordCount%> 個がクエリー “<%CiRestriction%>” を満たしています。
<%endif%>
</H5>

 <!– ここから結果セットの表示 –>
<%begindetail%>
<p>
<b><%CiCurrentRecordNumber%></b>
<b><a href=”<%EscapeURL vpath%>”><%filename%></a></b>
<b>要約:</b><%characterization%></b>
<font size=-1><%size%>bytes – <%write%></font>
<%enddetail%>
<!– ここまでが結果セットの表示 –>

<!–最後のページ以外には「次のページ」ボタンを定義します。–>
 <%if CiContainsFirstRecord eq 0%>
   <FORM ACTION=”search.idq”METHOD=”GET”>
<INPUT TYPE=”HIDDEN” NAME=”CiBookMark”VALUE=”<%CiBookMark%>”>
<INPUT TYPE=”HIDDEN” NAME=”CiBookMarkSkipCount”
VALUE=”-<%EscapeRAW CiMaxRecordsPerPage%>”>
<INPUT TYPE=”HIDDEN” NAME=”CiMaxRecordsInResultSet”
VALUE=”<%EscapeRAW CiMaxRecordsInResultSet%>”>
<INPUT TYPE=”HIDDEN” NAME=”CiRestriction” VALUE=”<%CiRestriction%>”>
<INPUT TYPE=”HIDDEN” NAME=”CiMaxRecordsPerPage”
VALUE=”<%EscapeRAW CiMaxRecordsPerPage%>”>
<INPUT TYPE=”HIDDEN” NAME=”CiScope” VALUE=”<%CiScope%>”>
<INPUT TYPE=”HIDDEN” NAME=”TemplateName” VALUE=”<%TemplateName%>”>
<INPUT TYPE=”HIDDEN” NAME=”CiSort” VALUE=”<%CiSort%>”>
<INPUT TYPE=”HIDDEN” NAME=”HTMLQueryForm” VALUE=”<%HTMLQueryForm%>”>
<INPUT TYPE=”SUBMIT” VALUE=”前の<%CiMaxRecordsPerPage%>文書”>
</FORM>

<%endif%>
 <%if CiContainsLastRecord eq 0%>
   <FORM ACTION=”search.idq”METHOD=”GET”>
<INPUT TYPE=”HIDDEN” NAME=”CiBookMark”VALUE=”<%CiBookMark%>”>
<INPUT TYPE=”HIDDEN” NAME=”CiBookMarkSkipCount”
VALUE=”<%EscapeRAW CiMaxRecordsPerPage%>”>
<INPUT TYPE=”HIDDEN” NAME=”CiMaxRecordsInResultSet”
VALUE=”<%EscapeRAW CiMaxRecordsInResultSet%>”>
<INPUT TYPE=”HIDDEN” NAME=”CiRestriction” VALUE=”<%CiRestriction%>”>
<INPUT TYPE=”HIDDEN” NAME=”CiMaxRecordsPerPage”
VALUE=”<%EscapeRAW CiMaxRecordsPerPage%>”>
<INPUT TYPE=”HIDDEN” NAME=”CiScope” VALUE=”<%CiScope%>”>
<INPUT TYPE=”HIDDEN” NAME=”TemplateName” VALUE=”<%TemplateName%>”>
<INPUT TYPE=”HIDDEN” NAME=”CiSort” VALUE=”<%CiSort%>”>
<INPUT TYPE=”HIDDEN” NAME=”HTMLQueryForm” VALUE=”<%HTMLQueryForm%>”>
<INPUT TYPE=”SUBMIT” VALUE=”次の<%CiRecordsNextPage%>文書”>
</FORM>
<%endif%>
</BODY>
</HTML>

これら3つのファイルをスクリプトの実行許可があるディレクトリに置いて公開。
もっと凝ったことがしたければASPなりASP.netなりを書くことになる。


そしてIISの設定。特に2と4が重要で、今回これでハメられました。。

  1. search.idqを置くディレクトリはスクリプトの実行許可を与える。
  2. IISのWebサービス拡張でIndex Service (とApplication Service Provider)を有効にする。
  3. idqファイルはidq.dllに食わせるためIISでアプリケーションの拡張子マッピング設定をする。
    Windows Server 2003 の場合すでに設定されていた。idq.dllは%windir%\System32にある。
  4. インデックスサービスのカタログのプロパティの追跡タブでidqスクリプトがあるサーバを指定しておく。

 

最後に必要な拡張コンポーネントをインストールして再スキャン。(本当はIndex Serviceのカタログ設定時に行うのが効率よい)  Index Serviceは標準でテキスト、HTML、ワード文書、エクセルワークシート、なんかの中のキーワードを引っかけられるけど、それ以外のファイルはそのままでは無理で、それぞれのフォーマットに対応したIFilterというものをインストールすると検索対象になる。

今構成しているサーバではPDFの検索が必須事項だったので、PDF用のIFilterをインストールする。
http://www.microsoft.com/japan/sharepoint/server/downloads/IFilter.asp

にあるリンクからPDF用のIFilterをAdobe本家サイトから入手(無料です)
http://www.adobe.com/jp/support/downloads/pdfi_2611.html

ZipのIFilterもあるみたい。
http://www.citeknet.com/Products/IFilters/ZIPIFilter/tabid/69/Default.aspx

売り物でPDFにも対応している高機能なIFilterとか使えたらもっと便利になるかも。高い。
http://www.componentsource.co.jp/products/514028/8822/index.html

クエリを実行してPDFが引っかかってこればOK。これはにちょっと感動した。


いくつかの課題

・更新。インデックス サービスの脆弱性により、コードが実行される (871250) (MS05-003) 更新を適用しておく。
http://www.microsoft.com/japan/technet/security/Bulletin/MS05-003.mspx

・検索対象の権限 。IndexService.exeのファイルに記載されているけど、部署ごとに見られたくないものがある場合は、カタログを複数作成して分けることになる。

・使われたくないファイルのヒット。イントラサイトの公開フォルダにはたくさんのファイルがあり、未完成のファイルやリンクされておらず、使われたくないファイルなども多い。インデックスサービスはWeb巡回エンジンではないので、それらのファイルもすべて検索対象になる。非公開のフォルダに移すか積極的に削除する必要がある。


これでよく使う文書フォーマットに対応したイントラネット検索サービスが開始できました。適当なキーワードで検索してみると意外な発見があるかも。

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中