スタッフブログ

  • カテゴリ 技術全般 の最新配信
  • RSS

WEKOで使われている全文検索の方法

naoto : 技術全般 2009/1/13 9:52

Blogger's Avatar

なおとです。 先週とある指令を受けて、WEKOに興味を持ちました。

ブログの記事を読むと、弊社の龍司社長はオフィス文書の検索に感心したようです。 そこに焦点を当てて調べてみました。

まずWEKOモジュールをダウンロードして、ソースを眺めてみることにします。

  • weko1.31.tar.gz

私は弊社の他のメンバーと違ってNetCommons2の経験が少々足りないので、勉強を兼ねて手探り状態です。

始めに、データベースのテーブル定義を見ます。 同時に日本語の言語ファイルも見て、関係がありそうなところにアタリをつけていきます。

  • repository/sql/mysql/table.sql
  • repository/language/japanese/main.ini

すでに前記の記事で書かれているように、検索エンジンとして、MySQLに標準で組み込まれている全文テキスト検索(FULLTEXT INDEX)が使われているようです。

これで検索用インデックスが格納されるテーブルの名前「repository_fulltext_data」が分かりました。

※Windows上で動いているなどで対応していない場合には、部分一致検索(LIKE検索)に切り替えるようです。

そこでテーブル名をキーにソースを全文検索すると、次の2つのファイルが該当することが分かりました。

  • repository/components/RepositoryAction.class.php
  • repository/action/edit/createfulltext/Createfulltext.class.php

ここまで絞り込まれると、あとはソースを読むだけです。

オフィス文書をテキスト形式のデータに変換する

この仕組みで検索可能にするためには、対象となる内容を予めテーブルに置き、さらにインデックスという、素早く効率的な検索をするための付加的なデータが必要です。まずはデータを登録する部分を見ていきます。

すると、PHPから外部のコマンドラインを呼び出して、オフィス文書をテキスト形式のデータに変換する処理を見つけました。 ごく簡単に、核心部分を引用します。

  • wvWare
    • wvHtml input.doc output.html
  • xlhtml
    • xlhtml input.xsl > output.html
  • poppler
    • pdftotext -enc UTF-8 input.pdf output.txt

詳しくは各ツールのマニュアルでコマンドライン・オプションを調べると分かります。 (例:man poppler)

検索用インデックスを作成〜実際に検索する

上記のように変換したテキストファイルの中身をテーブルに挿入したあと、インデックスを生成しています。

検索はデータベースに対して検索クエリを投げると、結果が帰ってきます。

最後の方は駆け足になりましたが、概要は以上です。

私は数年前に、Namazuを使った全文検索を扱ったことがありました。 wvWareやxlhtmlといったツールは、その時にも使われていたのを思い出しました。

検索インデックスを入れるためのテーブル定義
CREATE TABLE `repository_fulltext_data` (
  `item_id` INT,
  `item_no` INT,
  `extracted_text` LONGTEXT default "",
(中略)
   `is_delete` INT(1),
   FULLTEXT (`extracted_text`),
   PRIMARY KEY(`item_id`, `item_no`),
   KEY `item_id` (`item_id`, `item_no`)
);

テーブルに検索インデックスを構築する
CREATE FULLTEXT INDEX extracted_text ON repository_fulltext_data(extracted_text);

検索インデックスを持つテーブルを使って、検索する
SELECT item.item_id, item.item_no
 FROM repository_fulltext_data AS full, repository_item AS item
 WHERE full.item_id = item.item_id AND full.item_no = item.item_no
   AND item.is_delete = 0
   AND MATCH (full.extracted_text) AGAINST (?)
 ORDER BY order ASC;

トラックバック

スタッフブログ最新
カテゴリ一覧

〒104-0061 東京都中央区銀座1丁目3番3号 G1ビル7階
お問い合わせ TEL 03-3524-8860

Copyright(c) 2012 RYUS.All Rights Reserved.