日本語検索時の 簡易CJK処理 に変わるindexes方法

Events happening in the community are now at Drupal community events on www.drupal.org.
Anonymous's picture

DrupalのSearch moduleで日本語を検索しようとすると、ちゃんと検索結果が返って来ないことがあります。
これはノードをSearch moduleが文字列を半角スペース毎にインデクスしているからです。

これに対する簡易的な処理として簡易CJK処理(日本語環境だと標準でON)という機能があります。
簡易CJK処理は「単語の最少文字数」を設定し連続して重なり合う文字列へ分割します。
「単語の最少文字数」設定が 3 の場合、「こんにちは」という文章は「こんに」「んにち」「にちは」のように分割され、インデックス付けされます。

ですが、単にぶつ切りにしたものをインデクスするので、

  • 検索精度が悪い、
  • データベースが意味のないキーワードで肥大化する。
  • 検索単語の最小値が「単語の最少文字数」になってしまう。

という問題があります。

この日本語の検索問題に対して以下何れかの方法で対応しようと思いますが、
意見やアイディアなどあればコメントをお願いします。

・MeCab(メカブ)を使用した形態素分析
公式ページ http://mecab.sourceforge.net/

・Chinese Word Splitter(中文分词) module へ日本語辞書を寄贈
モジュール配布ページ http://drupal.org/project/csplitter

・TSearch2を使用した全文検索(textsearch-ja)
TSearch2のインストール例 http://a98.jugem.jp/?eid=366
http://textsearch-ja.projects.postgresql.org/index-ja.html

MeCab(メカブ)を使用した形態素分析

利点:

  • 定評の有り、日本語形態素分析で精度、速度ともに高い
  • PHP Extensionを使用することで開発も容易
  • データーベースの型に依存しない

欠点:

  • Mecabがインストールされていない場合はインストールが必要
  • レンタルサーバーなどではインストールできない
  • 文章の解析(「てにをは」で分けたり)をするので少しインデックスに時間がかかる

以下、Search Moduleを直接編集してMeCabによるインデクスの作成をしてみました。
search_simplify の内部関数でインデクス文を作成しているみたいなので、
hookでは難しいように思えます。何かいい方法はあるでしょうか?

function noun_filter($node_info)
{
    //var_dump($node_info);
    return $node_info['posid'] >= 37 && $node_info['posid'] <= 66;
}

function search_simplify($text) {
  ...

  // Simple CJK handling
  if (variable_get('overlap_cjk', TRUE)) {
    if(function_exists('mecab_split')) {
      $nouns = mecab_split($text, null, null, 'noun_filter');
   $text = '';
     
   foreach($nouns as $noun => $value) {
      //$text .= $value.' ';
       $text .= mb_convert_kana($value,'a').' ';
    }
    } else {
        $text = preg_replace_callback('/['. PREG_CLASS_CJK .']+/u', 'search_expand_cjk', $text);
    }
  }

Chinese Word Splitter Module

利点:

  • Moduleのインストールのみで済む
  • B+木構造なので辞書のファイルサイズも肥大化しない

欠点:

  • B+木構造の日本語辞書データの作成が必要
  • 辞書データーに入ってない文字はインデクスされない(?要確認)

TSearch2を使用した全文検索(textsearch-ja)

利点:

  • 比較的高速な検索が可能
  • Ngram形式と形態素解析形式を選ぶことができる
  • Ngram形式だと LIKE 中間一致検索に近い結果を得ることができる

欠点:

  • データーベースがpostgresqlで無いと動作しない
  • 形態素解析形式の場合はMecabのインストールが必要
  • Ngram形式の場合はSennaのインストールが必要
  • 文章の解析(「てにをは」で分けたり)をするので少しインデックスに時間がかかる
AttachmentSize
indexes.png546.23 KB

Comments

kuwamura's picture

くわむらです

・TSearch2を使用した全文検索
TSearch2のインストール例 http://a98.jugem.jp/?eid=360

あとで気が付いたのですが、そのページのダーティハックは必要なくなっています。

それから、MeCab の rpm を含めてCentOS にインストールしたときのログがあります。

http://a98.jugem.jp/?eid=366

形態素解析の欠点として、文章の解析(「てにをは」で分けたり)をするので少しインデックスに時間がかかるという欠点もあります。このため、 最近の textsearch_ja モジュールには、形態素解析の代わりにNgram方式でインデックスする sena に対応したものもできています。

最近、Servermans@VPS の490円のVPSサーバで遊んでいます。リソースはそれなりに小さいのですが、
結構性能はよくて面白いです。

J.kuwamura

くわむらさん、ご指摘ありがとうございます! Drupalで

jun784's picture

くわむらさん、ご指摘ありがとうございます!

Drupalで日本語検索について調べた際に、
サイトの方参照させて頂きました、ありがとうございます _ _)m

Tsearchは綺麗にインストールできるんですね、
現状自分のサイトではmecabを直接叩いてのダーディハックなのでぜひ試してみたいのですが、
Mysql形式なのとFaceted Search Module などを組み合わせているのでSearch moduleのインストールが必須なのがネックになってます。

やはり環境に依存せず汎用的に扱えるものとして、
Chinese Splitterがやはりいいのかなと思っていますー。

Editnote:
Tsearch2の参照URL、利点、欠点を修正しました。

日本 コミュニティ: Drupal Japan User Group

Group organizers

Group categories

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds: