用PHP实现Ngram(双字模)

经过。

我想在MySQL中进行全文搜索,所以我查找了以下的文章并发现需要实现Ngram(二元模型),所以我尝试着创建了它。

听说MYSQL5.7及更高版本已经自带了日本语的Ngram解析器,所以应该选择MYSQL5.7及更高版本。
但是似乎也存在这样的一个行为。

以下的设置很容易被忘记,请注意。

[mysqld]
innodb_ft_min_token_size=2

总结

我們預計在CMS中,除了儲存HTML之外,還會準備一個專供搜尋使用的欄位,作為搜尋字串的使用。

代码 (Mandarin Chinese translation of “code”)

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筛选了结果。
(注:在使用二元组进行搜索时,请使用至少两个字符进行搜索。)

在数据库中搜索从「あいうえおか」到「うえお」的示例。
在数据库中存储的是「あい いう うえ えお おか か」。

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

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