Menu
Wiki内検索
最近更新したページ

cakePHP キーワード検索

キーワード検索の種類

まずは色々ある検索方法の語彙の説明
  • 前方一致:指定したキーワードから始まる言葉を検索
  • 後方一致:指定したキーワードで終わる言葉を検索
  • 完全一致:指定したキーワードに完全に一致する言葉を検索

指定したキーワードが言葉の真ん中にある場合の呼び方は分かりません。

今回はSQLを使ってこれら4つの実装方法を紹介する。

説明のためのテーブルは以下の形とする。

SAMPLE
idtitleauther
1java入門滋芭遼太郎
2java応用中西礼
3C++入門芥川龍之介
4C++応用中川みゆき
5PHP滋賀直哉
6MySQL武者小路龍太郎


LIKE・ワイルドカードを使う

基本の構文はこの通り

SELECT * FROM テーブル名 WHERE フィールド名 LIKE 'キーワード'
この時のキーワードにワイルドカードを使うことが出来る。

%任意の長さ(ゼロを含む)の文字列
_任意の1文字

例えば A_C の場合は
OK: ABC AZC ZATC
OUT: AC AABC

同様に A%Cの場合は
OK: AC AAC AABC BABC
OUT: BBBC AAA

上のテーブルで例を挙げると
SELECT * FROM SAMPLE WHERE 'title' LIKE 'java%'
その結果はこの通り
idtitleauther
1java入門滋芭遼太郎
2java応用中西礼

また、検索をANDやORで連結することもできる。
SELECT * FROM SAMPLE WHERE 'auther' LIKE '%川%' OR 'auther LIKE '%龍%'
その結果はこの通り
idtitleauther
3C++入門芥川龍之介
4C++応用中川みゆき
6MySQL武者小路龍太郎


INDEXを利用する

上記の方法では全行に対して評価を行うために、行数が多くなると実行時間が増大していく。
それを軽減する方法としてINDEXがある。

インデックスは、カラムが特定の値をもつレコードの迅速な検索に使用され、クエリ対象のカラムにインデックスがあると、MySQLは全てのデータを探すことなく、迅速に取得することができる。

ただし、INDEXを作成するとデータ追加や更新の速度が低下するため、頻繁に更新する場合は
  1. インデックスを一度削除する。
  2. データを一気に追加
  3. インデックスを再登録
このようにするとただ登録するよりも速いことが多い

INDEXについての詳しいことはMySQL:インデックスまとめメモを参照の事。


phpmyadminでINDEXの作成

PHPMYADMIN-構造
上の画像の赤枠内がINDEXの表となっている。

今回はbooksテーブルのtosho_name, bunsyo_kenmei, ukeoi_nameにINDEXを張ることとする。
そのため、赤枠内の「3つのカラムにインデックスを作成する」を選ぶ。

するとこの画面となる⇒インデックス作成

インデックス名は自由に設定。今回はstringとした。
インデックスの種類は最も重要で、ここの欄をFULLTEXTとする。
あとはその下のフィールドにtosho_name, bunsyo_kenmei, ukeoi_nameを当て、このまま保存だと容量が足りないと出て作成できないため、ここではtosho_name, bunsyo_kenmeiの2つのサイズを333とした。

すると赤枠内に作成したINDEXが表示される。


INDEXを使った検索

この時に使う構文は以下のもの。

SELECT * FROM テーブル名 WHERE MATCH(インデックスを張ったカラム名) AGAINST('調べたいキーワード');
先ほど使ったテーブルの内、titleとautherにインデックスを張ったとする。
そして以下のSQLを発行する。

SELECT * FROM SAMPLE WHERE MATCH(title) AGAINST('C++入門');

するとこの結果が出る(はず)。

idtitleauther
3C++入門芥川龍之介


色々使ってみたけれど、どうも前文一致の検索のようで、あいまい検索をしたいときは下の構文を使いましょう。



また、このような構文もある。
SELECT * FROM テーブル名 WHERE MATCH(インデックスを張ったカラム名) AGAINST('調べたいキーワード' in boolean mode );
これのキーワードにはワイルドカード他を使うことが出来るようで。参照⇒MySQL :: MySQL 4.1 リファレンスマニュアル :: 6.8 MySQL 全文検索

これだと、

SELECT * FROM SAMPLE WHERE MATCH(title) AGAINST('C++*' in boolean mode );
とすると

idtitleauther
3C++入門芥川龍之介
4C++応用中川みゆき
といった結果が出る。

ただ、前方一致にあたるので、後方一致や真ん中一致は使えません。が、+やー、""をつかうことで多くの条件を比較的短い文で検索できるので基本はこれでいいかもしれない。

LIKEを使う時と比較するとはるかに速いようです。参照⇒MySQL FULLTEXT + Ngram : LIKE検索より数十倍高速な、お手軽 日本語全文検索 について|blog|たたみラボ


追記
やはり、MySQLで日本語での検索は色々と問題があるようでその対策がいるようで。
Tritonnプロジェクト - Tritonnプロジェクト 〜 MySQL+Sennaによる全文検索 〜
↑のとかを入れると日本語でもできるみたい?
動作確認してからwikiに記録します。


2008年10月27日(月) 01:17:46 Modified by kindaisis_student06

添付ファイル一覧(全2件)
8d09b14c0b8ee958.jpg (102.64KB)
Uploaded by kindaisis_student06 2008年10月25日(土) 15:23:18
cdc932ec2f5b828c.jpg (199.62KB)
Uploaded by kindaisis_student06 2008年10月25日(土) 15:23:18