
オープンソースのナレッジベースKBPublisherの検索方法を「match...against」から「Like %キーワード%」に変更して日本語のキーワードでもきちんとヒットするようにするコード変更について覚書。
記事概要
オープンソースのナレッジベースKBPublisherは、ナレッジベース内の記事を検索する際にMySQLのフルテキストインデックスを利用した「match...against」で検索を行う。
MySQLのフルテキストインデックスは日本語には対応していないため、日本語のキーワードで検索をしてもヒットしない。
MeCabやSennnaなどを利用してMySQLのフルテキストインデックスを日本語対応にする方法もあるが、あまりお手軽な方法とは言えない。
MySQLのフルテキストインデックスの詳細については、「MySQLで全文検索 - FULLTEXTインデックスの基礎知識」などを参考。
日本語文字列の検索に関しては、過去の記事に書いたように"ft_min_word_len=1"を設定することで若干のヒット率を上げることはできたが完ぺきではない。

ヒットするはずのキーワードでヒットしなければナレッジベースとしては役に立たない。
仕方ないので、「match...against」検索を「Like %キーワード%」で検索するようにコードを修正し、さらに半角スペース、もしくは、全角スペースで区切られたキーワードを「AND」検索するように修正した。
変更対象ファイルと変更箇所
以下に変更を行ったファイルと変更箇所について記載する。
変更対象ファイル
変更対象ファイルは"kb\client\inc"フォルダ内の以下のファイル。
KBClientSearchGenerator.php
変更箇所
"KBClientSearchGenerator.php"の157~158行を削除し、以下のコードを貼り付ける。
変更前:
$sql['select'] = "MATCH (title, body, meta_keywords, meta_description) AGAINST ('$str') AS score";
$sql['where'] = "MATCH (title, body, meta_keywords, meta_description) AGAINST ('$str' IN BOOLEAN MODE)";
変更後:
$str = mb_convert_kana($str, "s","utf-8");//全角スペースだったら半角スペースに変換
$wordList = explode(' ',$str);
for ($i = 0; $i < count($wordList); $i++) {
$wordList[$i] = "(title LIKE '%{$wordList[$i]}%' OR body LIKE '%{$wordList[$i]}%')";
}
$whereArr[] = implode(' AND ', $wordList);
$where = implode(' AND ', $whereArr) ;
$where = $where;
$sql['select'] = "MATCH (title, body, meta_keywords, meta_description) AGAINST ('$str') AS score";
$sql['where'] = $where;
書き替えたら上書き保存。
以上で終了。
このコードに変更することにより、記事(ナレッジコンテンツ)のタイトル(title)と詳細部分(body)を対象にLike検索を行う。
また、半角/全角スペースでキーワードを区切ることにより区切られたキーワードを「AND」検索する。
例えば、"エラー データベース"で実行される検索条件(Where句)は、以下のようになる。
(title LIKE '%エラー%' OR body LIKE '%エラー%') AND (title LIKE '%データベース%' OR body LIKE '%データベース%')
補足
日本語は英語のように単語間の区切りがあるような言語ではないため、MySQLのフルテキストインデックス機能を使ってもあまり意味はない。
言語差異によるものなので、英語ベースのオープンソースソフトウェアを使用する際にはどうしてもこういった問題は避けられない。

コメント