FMK
devel****@fmk*****
2014年 7月 30日 (水) 19:30:10 JST
こんばんは。中村です。
須藤様、村上様、
ご回答ありがとうございます。
まずは、実際にSQLをたたいてみました。本文後半に操作ログを列記いたします。
やはり、中黒「・」ありの文章を中黒「・」ありのキーワードで全文検索すると、
文脈次第でヒットしない例が再現されました。
目指すものとしましては、WEBの検索画面などで「アル・カポネ」と入力した場合、
きちんと該当するキーワードを含むコンテンツを表示することにございます。
そこで、1つの解法として全文検索用のテーブルを別個用意し(実データを含むテーブルとはリレーションを張る)、
「アル・カポネ」から中黒「・」を除去した「アルカポネ」を格納し、
全文検索時も「・」を除去した「アルカポネ」で検索することを思いつきました。
(検索結果には実データを含むテーブルの原文を表示する)
昨日、ゆらぎの吸収と申したのは、「アル・カポネ」でも「アルカポネ」でも検索ができることでした。
ただし、単純に中黒「・」を除去しただけの場合、例えば、
「イネ・ムギ・ブナ・アカマツ」のように同格の名詞を列挙した場合、
単純な中黒抜きだと「ムギ」では検索できなくなるという悪影響があります。→末尾
まずは何より検索漏れを防ぎたい、というのがございますので、
トークナイザーとノーマライザーをこのまま使う場合は、
村上様に頂いたヒントに基づき、
IPAdic辞における「・」の調整が有効かと思いました。
(自分の手を動かしていないため断言はできませんが)
環境はRPMでザクザク導入していますので、再コンパイルなど道のりが長そうです…。
$ rpm -qa | grep mecab
mecab-0.996-1.el6.x86_64
groonga-tokenizer-mecab-4.0.4-1.el6.x86_64
mecab-ipadic-2.7.0.20070801-8.el6.1.x86_64
mecab-devel-0.996-1.el6.x86_64
引き続き調査いたします。
よろしくお願いします。
----------
【問題の再現】
1) テーブル作成
CREATE TABLE diaries (
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
content LONGTEXT NOT NULL,
PRIMARY KEY(id),
FULLTEXT INDEX (content) COMMENT 'parser "TokenMecab", normalizer "NormalizerAuto"'
) ENGINE = mroonga COMMENT = 'engine "innodb"' DEFAULT CHARSET utf8mb4 COLLATE = utf8mb4_unicode_ci;
2) 文章投入
mysql> INSERT INTO diaries (content) VALUES('映画の題材にもなったギャングのアル・カポネは有名です。');
Query OK, 1 row affected (0.05 sec)
mysql> INSERT INTO diaries (content) VALUES('アメリカ禁酒法時代の代表的なギャングとしてアル・カポネが挙げられます。');
Query OK, 1 row affected (0.02 sec)
mysql> SELECT content FROM diaries;
+-----------------------------------------------------------------------------------------------------------+
| content |
+-----------------------------------------------------------------------------------------------------------+
| 映画の題材にもなったギャングのアル・カポネは有名です。 |
| アメリカ禁酒法時代の代表的なギャングとしてアル・カポネが挙げられます。 |
+-----------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
3) LIKEで検索
mysql> SELECT content FROM diaries WHERE content LIKE '%アル・カポネ%';
+-----------------------------------------------------------------------------------------------------------+
| content |
+-----------------------------------------------------------------------------------------------------------+
| 映画の題材にもなったギャングのアル・カポネは有名です。 |
| アメリカ禁酒法時代の代表的なギャングとしてアル・カポネが挙げられます。 |
+-----------------------------------------------------------------------------------------------------------+
2 rows in set (0.02 sec)
4) 全文検索で検索
mysql> SELECT content FROM diaries WHERE MATCH (content) AGAINST ("+アル・カポネ" IN BOOLEAN MODE);
+-----------------------------------------------------------------------------------------------------------+
| content |
+-----------------------------------------------------------------------------------------------------------+
| アメリカ禁酒法時代の代表的なギャングとしてアル・カポネが挙げられます。 |
+-----------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
【中黒「・」を抜く】
1) 中黒「・」を抜いた文章を再投入
mysql> DELETE FROM diaries;
Query OK, 2 rows affected (0.03 sec)
mysql> INSERT INTO diaries (content) VALUES('映画の題材にもなったギャングのアルカポネは有 名です。');
Query OK, 1 row affected (0.02 sec)
mysql> INSERT INTO diaries (content) VALUES('アメリカ禁酒法時代の代表的なギャングとしてア ルカポネが挙げられます。');
Query OK, 1 row affected (0.03 sec)
2) 全文検索で検索
mysql> SELECT content FROM diaries WHERE MATCH (content) AGAINST ("+アルカポネ" IN BOOLEAN MODE);
+--------------------------------------------------------------------------------------------------------+
| content |
+--------------------------------------------------------------------------------------------------------+
| アメリカ禁酒法時代の代表的なギャングとしてアルカポネが挙げられます。 |
| 映画の題材にもなったギャングのアルカポネは有名です。 |
+--------------------------------------------------------------------------------------------------------+
2 rows in set (0.01 sec)
【イネ・ムギ・ブナ・アカマツ】
mysql> SELECT content FROM diaries WHERE MATCH (content) AGAINST ("+イネ" IN BOOLEAN MODE);
+--------------------------------+
| content |
+--------------------------------+
| イネムギブナアカマツ |
+--------------------------------+
1 row in set (0.01 sec)
mysql> SELECT content FROM diaries WHERE MATCH (content) AGAINST ("+ムギ" IN BOOLEAN MODE);
Empty set (0.00 sec)
--