Tasuku SUENAGA
a****@razil*****
2006年 9月 15日 (金) 17:48:45 JST
末永です。
> --------
> select PART_ID from REP_PART
> where PART_WORD like '%提携%';
> --------
> でヒットするレコードが、
>
> --------
> select PART_ID from REP_PART
> where match(PART_WORD) against('*提携*' in boolean mode);
> --------
> ではヒットしないという状況で悩んでおります。
>
> 全てのレコードがヒットしない訳ではなく、
> like 検索で140件のところ、
> match against では134件しかヒットせず、
> 6件のモレが出ているという状況です。
> モレのない検索を like より高速に実現できないかと
> sennaの導入を検討しているのですが、
> 部分一致検索のしかたが間違っているのでしょうか。
まず、クエリについては、
select PART_ID from REP_PART
where match(PART_WORD) against('提携' in boolean mode);
でよいと考えます。
--
Sennaは、
デフォルトでMeCabによる形態素解析を用いたインデックスを作成します。
この場合、
基本的には単語と一致したものしか検索結果としてヒットしません。
例えば、
「屋外使用前提携帯電話」という文書があった場合を考えます。
この文書は、
「屋外 使用 前提 携帯 電話」と分かち書きされます。
この文書には、
「提携」という「部分文字列」は含まれていますが、
「提携」という「単語」は含まれていないため、
検索結果に入れないようにしています。
なぜなら、
検索したユーザが求めている文書である可能性が低いためです。
「京都」で検索して、「東京都」が出てもうれしくないよね、という話です。
コマンドラインのMeCabで
モレている6件の文書を解析してみてください。
(例えば、mecab -O wakati < bunsyo.txt)
「提携」という「単語」が存在していないと思います。
--
さて、
通常の形態素解析ベースの検索エンジンでしたら
上記の説明で話が終わってしまうのですが、
Sennaの場合は単語の部分一致検索が可能です。
「提携」という単語で検索を行った場合、
ヒット数が0件であった場合に限り、
単語の部分一致検索を行います。
http://qwik.jp/senna/query.htmlにあるとおり、
最初から全ての手法による検索を行う場合には、
select PART_ID from REP_PART
where match(PART_WORD) against('*E-7提携' in boolean mode);
というSQLを実行します。
おそらく所望の結果が得られるはずです。
ヒット数のしきい値も、
*Eのパラメータによって指定できます。
--
今回のケースであれば、
N-gram方式でインデックスを作成したほうがよいと考えます。
テーブル作成の際に、
create table REP_PART (
PART_ID varchar(6),
PART_WORD mediumtext,
primary key (PART_ID),
fulltext index using NGRAM (PART_WORD)
);
とすると、
「提携」という単語のヒット数がlike検索と一緒になると思います。