This is my Github fork of the Searchable Behaviour project on Google Code. The project holds an MIT Licence and credit/copyright goes to Calin for such a great effort.

This behaviour allows Cake developers to make a model fulltext searchable, meaning that the user will be able to perform mysql fulltext search (which powers Wikimedia for example) on the models.

For example, a fulltext search allows end users to use boolean expressions (eg. '-' to exclude a term) or natural language search which interprets the search string as a phrase in natural human language.

Setup

To setup this behaviour you will need to create the following MySQL table

CREATE TABLE `search_indices` (
	`id` int(11) NOT NULL auto_increment,
	`association_key` varchar(36) NOT NULL,
	`model` varchar(128) collate utf8_unicode_ci NOT NULL,
	`data` longtext collate utf8_unicode_ci NOT NULL,
	`created` datetime NOT NULL,
	`modified` datetime NOT NULL,
	PRIMARY KEY  (`id`),
	KEY `association_key` (`association_key`,`model`),
	FULLTEXT KEY `data` (`data`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Model setup

To create indices for model data, you have to add the Searchable behavior to the model.

Create index all model fields

<?php
class Post extends AppModel {
    var $name = 'Post';
    var $actsAs = array('Searchable.Searchable');
}
?>

Create index for only for headline and text fields:

<?php
class Post extends AppModel {
    var $name = 'Post';
    var $actsAs = array(
        'Searchable.Searchable' => array(
            'fields' => array(
                'headline',
                'text',
            )
        )
    );
}
?>

Stopwords:

Stopwords can be found in the config/stopwords.php file

<?php
class Post extends AppModel {
    var $name = 'Post';
    var $actsAs = array(
        'Searchable.Searchable' => array(
            'stopwords_lang' => 'german'
        )
    );
}
?>

Usage

At your disposal, there are several ways to use it:

SearchIndex Model

You can use the SearchIndex model to do the searches using the regular cake php ** Model->find() **. By default this will search all the subjects (if you have more than one searchable model). To search only ceratin models you can use SearchIndex->searchModels()

An example usage, using cakephp pagination:

<?php
	$this->SearchIndex->searchModels(array('Post','Comment'));
	$this->paginate = array(
		'limit' => 10,
		'conditions' =>  "MATCH(SearchIndex.data) AGAINST('$q' IN BOOLEAN MODE)"
	);
	$this->set('results', $this->paginate('SearchIndex'));
?>

The searchable model

To do a search on the actual searchable model, you can use Model->search(query)

Indexing data

To provide a custom indexing function, you can define your own indexData() function. By default all varchar, char and text fields are indexed.

<?php
class Comment extends AppModel {

	var $name = 'Comment';
	var $actsAs = array(
        'Searchable.Searchable' => array(
            'fields' => array('text')
        )
    );
	
	function indexData() {
		$index = $this->data['Comment']['text'];
		return $index;
	}
}
?>

Rebuild index from shell

To rebuild the index from shell, you can run the wizard

app/Console/cake Searchable.Searchable index

Or you can speficy for which modely you want to rebuild the index

app/Console/cake Searchable.Searchable index <database config> <model name>

Rebuild index for all models with the searchable behaviour

app/Console/cake Searchable.Searchable index default all

Rebuild index for post and comments models

app/Console/cake Searchable.Searchable index default Post,Comment

Rebuild index only for comments models

app/Console/cake Searchable.Searchable index default Comment