LoginSignup
5
7

More than 3 years have passed since last update.

PHPでNgram(バイグラム)

Last updated at Posted at 2017-10-21

経緯

MySQLでの全文検索用をしたかったので知らべていたところ以下の記事
でNgram(バイグラム)の実装が必要になりそうだったので作成してみました。

MYSQL5.7以降だと既に日本語のNgramパーサーが入っているそうなのでMYSQL5.7以降はこちら
但しこんな動作もあるらしいです。

以下の設定は忘れやすいので注意

[mysqld]
innodb_ft_min_token_size=2

概要

CMSでhtmlを保存するのとは別に検索用カラムを用意して検索用文字列として使用する想定です。

コード

class Bigram
{
    /**
     * 文字列を登録・検索用バイグラムに変換する
     *
     * @param string|null $string
     * @param boolean $for_search_flag
     *     false:DB保存時に使用する変換方法 あいう→あい いう う
     *     true:検索時に使用する変換方法 あいう→あい いう 1文字の場合は空文字を返します(そもそも2文字以上で検索しないとヒットしないので構わない)
     * @return string|null
     */
    public function convert_to_bigram(string $string = null, bool $for_search_flag = false)
    {
        if (is_null($string))
        {
            return null;
        }

        $string = str_replace(array(" ", " ", "\r", "\n", "\t"), "", $string);
        $string = strip_tags($string);
        $character_list = preg_split("//u", $string, -1, PREG_SPLIT_NO_EMPTY);// 1文字づつ配列に分ける

        $bigram = '';// バイグラム

        $glue = '';
        foreach ($character_list as $index => $character)
        {
            if (isset($character_list[$index + 1]))
            {
                $bigram .= $glue.$character.$character_list[$index + 1];
            }
            else
            {
                if ($for_search_flag === false)
                {
                    $bigram .= $glue.$character;
                }
            }
             $glue = ' ';
        }

        return $bigram;
    }

}

$string = "<p><div><a>あ い\t う え\nおか</a></div></p>";
$bigram = new Bigram();
var_dump($bigram->convert_to_bigram($string));
var_dump($bigram->convert_to_bigram($string, true));

結果

string(38) "あい いう うえ えお おか か"
string(34) "あい いう うえ えお おか"

確認

その他

for_search_flagで結果を分けたのは検索時用のバイグラムが必要になったためです。
※バイグラムで検索する際は2文字以上で検索すること

「あいうえおか」から「うえお」で検索する例
DBで持つのは「あい いう うえ えお おか か」

match(`bigram`) against('+"うえ えお" in boolean mode')
ではヒットするが

match(`bigram`) against('+"うえ えお お" in boolean mode')
だとヒットしない
5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7