cakePHP キーワード検索
キーワード検索の種類
まずは色々ある検索方法の語彙の説明- 前方一致:指定したキーワードから始まる言葉を検索
- 後方一致:指定したキーワードで終わる言葉を検索
- 完全一致:指定したキーワードに完全に一致する言葉を検索
指定したキーワードが言葉の真ん中にある場合の呼び方は分かりません。
今回はSQLを使ってこれら4つの実装方法を紹介する。
説明のためのテーブルは以下の形とする。
SAMPLE
| id | title | auther |
| 1 | java入門 | 滋芭遼太郎 |
| 2 | java応用 | 中西礼 |
| 3 | C++入門 | 芥川龍之介 |
| 4 | C++応用 | 中川みゆき |
| 5 | PHP | 滋賀直哉 |
| 6 | MySQL | 武者小路龍太郎 |
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%'その結果はこの通り
| id | title | auther |
| 1 | java入門 | 滋芭遼太郎 |
| 2 | java応用 | 中西礼 |
また、検索をANDやORで連結することもできる。
SELECT * FROM SAMPLE WHERE 'auther' LIKE '%川%' OR 'auther LIKE '%龍%'その結果はこの通り
| id | title | auther |
| 3 | C++入門 | 芥川龍之介 |
| 4 | C++応用 | 中川みゆき |
| 6 | MySQL | 武者小路龍太郎 |
INDEXを利用する
上記の方法では全行に対して評価を行うために、行数が多くなると実行時間が増大していく。それを軽減する方法としてINDEXがある。
インデックスは、カラムが特定の値をもつレコードの迅速な検索に使用され、クエリ対象のカラムにインデックスがあると、MySQLは全てのデータを探すことなく、迅速に取得することができる。
ただし、INDEXを作成するとデータ追加や更新の速度が低下するため、頻繁に更新する場合は
- インデックスを一度削除する。
- データを一気に追加
- インデックスを再登録
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++入門');
するとこの結果が出る(はず)。
| id | title | auther |
| 3 | C++入門 | 芥川龍之介 |
色々使ってみたけれど、どうも前文一致の検索のようで、あいまい検索をしたいときは下の構文を使いましょう。
また、このような構文もある。
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 );とすると
| id | title | auther |
| 3 | C++入門 | 芥川龍之介 |
| 4 | C++応用 | 中川みゆき |
ただ、前方一致にあたるので、後方一致や真ん中一致は使えません。が、+やー、""をつかうことで多くの条件を比較的短い文で検索できるので基本はこれでいいかもしれない。
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
Uploaded by kindaisis_student06 2008年10月25日(土) 15:23:18
cdc932ec2f5b828c.jpg (199.62KB)
Uploaded by kindaisis_student06 2008年10月25日(土) 15:23:18
Uploaded by kindaisis_student06 2008年10月25日(土) 15:23:18