CakePHPからToritonnの全文検索を使う方法
お手軽につかえる検索エンジンとして、Senna+MySQLで作られたToritonnがありますね。
弊社のWebサービス「nanapi」でも検索エンジンには、Toritonnを使っています。MySQLベースなので、CakePHPのActiveRecordがつかえて便利です。ただ、Toritonn使うときはSQLが拡張されているためちょっと工夫が必要です。
今回はCakePHPからToritonnを使うコツを紹介します。
テーブルを作成する
まずはテーブルを作成しましょう。本家のサイトのあるようにとりあえずはこんな感じで。
CREATE TABLE search ( id INTEGER AUTO_INCREMENT, PRIMARY KEY (id), text TEXT NOT NULL, FULLTEXT INDEX USING NGRAM (text) );
全文検索を使ってみる
このテーブルに対して全文検索をかけたいときはこんな感じです。
<?php $query = 'MATCH ( text ) AGAINST ("foo")' ; $opt = array( 'conditions' => array( $query ), ); $search = $this->Search->find('all',$opt);
AND検索を使ってみる
次はAND検索をつかってみたい場合。BLOOLEAN MODEを使います。
<?php $query = 'MATCH ( text ) AGAINST ("+foo +bar" IN BLOOLEAN MODE)' ; $opt = array( 'conditions' => array( $query ), ); $search = $this->Search->find('all',$opt);
スコアでソートしてみる
検索結果に対してスコアをつけて、ソートさせることもできます。自動的にソートしてくれないので、ちょっと頑張らないといけません。あまりキレイな方法ではありませんが、以下のようにfieldsを指定してやることで解決。
<?php $query = 'MATCH ( text ) AGAINST ("foo" IN BLOOLEAN MODE)'; $opt = array( 'fields' => array('Search.id','Search.text',$query . ' AS score') , 'conditions' => array($query), 'order' => 'score DESC', ); $search = $this->Search->find('all',$opt);
マルチセクション機能を使ってソートしてみる
複数カラムにまたがったデータを検索するときは、マルチセクション機能を利用します。テーブルはこんな感じで作成してください。
CREATE TABLE search ( id INTEGER AUTO_INCREMENT, PRIMARY KEY (id), text1 TEXT NOT NULL, text2 TEXT NOT NULL, FULLTEXT INDEX USING NGRAM, SECTIONALIZE (text1,text2) );
<?php $query = 'MATCH ( text1 , text2 ) AGAINST ("W1,W2 foo" IN BLOOLEAN MODE)'; $opt = array( 'fields' => array('Search.id','Search.text',$query . ' AS score') , 'conditions' => array($query), 'order' => 'score DESC', ); $search = $this->Search->find('all',$opt);
便利ですねー。