Search feature to CakePHP blog example

By Calin Don (calin)
Using searchable behavior, exemplified on CakePHP's blog example from documentation.

Hello everybody!

First of all I assume that you have read and tried the blog example form documentation http://book.cakephp.org/view/219/blog).

Setup

So to get things started, we need to download seachable behavior from (http://code.google.com/p/searchable-behaviour-for-cakephp). Then we copy the archive contents to the /app folder. To complete the installation process there is one more thing to do: create the search table. So we run the following sql code:

Download code
CREATE TABLE `search_index` (
    `id` int(11) NOT NULL auto_increment,
    `association_key` int(11) 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;

So we are set up now, ready to add our nice search feature!

The actual search

First we need to add the searchable behavior to Post model.

Model Class:

Download code <?php 
<?php
// app/models/post.php
class Post extends AppModel
{
    var 
$name 'Post';
    var 
$actsAs = array ('Searchable');

    var 
$validate = array(
        
'title' => array(
            
'rule' => array('minLength'1)
        ),
        
'body' => array(
            
'rule' => array('minLength'1)
        )
    );
}
?>
?>

To be able to search, we need to place a search box somewhere. Add the following snippet of code just after the page heading.

Download code
<?php 
    
echo $form->create("Post",array('action' => 'search'));
    echo 
$form->input("q", array('label' => 'Search for'));
    echo 
$form->end("Search");
?>

We need to define the search action in our post controller.

Download code
<?php
    
function search() {
        
$this->set('results',$this->Post->search($this->data['Post']['q']));
    }
?>

Finally we create the view for search results (which is just a slightly modified version of posts index):

View Template:

Download code
<?php // app/views/posts/search.ctp ?>
<h1>Blog posts</h1>
<?php 
    
echo $form->create("Post",array('action' => 'search'));
    echo 
$form->input("q", array('label' => 'Search for'));
    echo 
$form->end("Search");
?>
<p><?php echo $html->link("Add Post""/posts/add"); ?>
<table>
    <tr>
        <th>Id</th>
        <th>Title</th>
                <th>Action</th>
        <th>Created</th>
    </tr>

<!-- Here's where we loop through our $results array, printing out post info -->

<?php foreach ($results as $post): ?>
    <tr>
        <td><?php echo $post['Post']['id']; ?></td>
        <td>
            <?php echo $html->link($post['Post']['title'],'/posts/view/'.$post['Post']['id']);?>
                </td>
                <td>
            <?php echo $html->link(
                
'Delete'
                
"/posts/delete/{$post['Post']['id']}"
                
null
                
'Are you sure?'
            
)?>
            <?php echo $html->link('Edit''/posts/edit/'.$post['Post']['id']);?>
        </td>
        <td><?php echo $post['Post']['created']; ?></td>
    </tr>
<?php endforeach; ?>
</table>

That's it! You now have a blog with a fully featured search engine.

For other ways of using the searchable behavior, check the project page on Google Code (http://code.google.com/p/searchable-behaviour-for-cakephp).

 

Comments 791

CakePHP Team Comments Author Comments
 

Comment

1 little bug

Hello,

You say that «By default all varchar, char and text fields are indexed.»
But this is not true because getColumnTypes will say varchar is 'string'

$columns = $this->model->getColumnTypes();

so just add

if (isset($columns[$key]) && in_array($columns[$key],array('string','text','varchar','char'))) {...}

Thanks for the behavior, great work :D
Posted Nov 12, 2008 by seb
 

Bug

2 a typo

In the code shown for the model class, you open and close the ?php tag twice.
Posted Nov 27, 2008 by Adriano Varoli Piazza
 

Comment

3 Thank you!

Thankyouthankyouthankyou! This is what I've been looking for all along!
Posted Nov 27, 2008 by Adriano Varoli Piazza
 

Comment

4 Extension request:

Something I'm struggling with is searching belongsTo relationships and returning the id of the object's parent, not of the actual object found.
Example:
I have a 'paintings' table (not the actual table/class name) that hasMany 'titles'. I'd like to search for one of the 'titles' (bonus points if that search can be done from the 'painting' views) and that the returned list showed the link to the actual 'painting', not to the 'title'.

I understand it's a lot to ask, so thanks in advance for _any_ help.
Posted Dec 9, 2008 by Adriano Varoli Piazza
 

Question

5 It doesn't search

Hello together,

i've tried it with my own application(a very very simple dictionary) I implemented directly to this docu...
But the searchreslut is always empty....

What i have to do that the result is correct.

my translation DB is

CREATE TABLE translates (
id int(10) unsigned NOT NULL auto_increment,
language1 varchar(255) NOT NULL,
language2 varchar(255) NOT NULL,
created datetime default NULL,
modified datetime default NULL,
PRIMARY KEY (id)
);

The search_index is the same...

Can erveryone help me. If i search then is no error message...

Thanks

Many greetings

Marcus Radisch
Posted Dec 17, 2008 by Marcus Radisch
 

Question

6 Whats wrong with this fulltext search

Hello

now i tried it with the official Blog Tutorial, but there is no way it doesnt search. Can every help me a little bit

many greetings

Marcus Radisch
Posted Dec 17, 2008 by Marcus Radisch
 

Comment

7 Re: Whats wrong with this fulltext search

Hello

now i tried it with the official Blog Tutorial, but there is no way it doesnt search. Can every help me a little bit

many greetings

Marcus Radisch

Try reading this link: http://code.google.com/p/searchable-behaviour-for-cakephp/issues/detail?id=2
Posted Dec 18, 2008 by Adriano Varoli Piazza
 

Question

8 Re: Whats wrong with this fulltext search

Hello

now i tried it with the official Blog Tutorial, but there is no way it doesnt search. Can every help me a little bit

many greetings

Marcus Radisch

Try reading this link: http://code.google.com/p/searchable-behaviour-for-cakephp/issues/detail?id=2

I tried ist, but there is no change is the result search engine doesn't search.

Whats the reason? I' don't know. Do you have any ideas?
Posted Dec 18, 2008 by Marcus Radisch
 

Bug

9 A german "umlaute" (äöüß) Bug

Hello

can everyone help me? I have added an Bug for this component under this link->http://code.google.com/p/searchable-behaviour-for-cakephp/issues/detail?id=9 Until this moment i don't found any solution

Many greeting

marcus radisch
Posted Dec 19, 2008 by Marcus Radisch
 

Question

10 How can i indexing my hole DB-Table

Hello,

thanks a lot for the great help. My Question is now, i have an DB-Table with 2 Columns. How can i great an searchindex over the Table?

many greatings

Marcus Radisch
Posted Dec 19, 2008 by Marcus Radisch
 

Comment

11 asking questions

Hello,

thanks a lot for the great help. My Question is now, i have an DB-Table with 2 Columns. How can i great an searchindex over the Table?

many greatings

Marcus Radisch

I understand you're not familiar with English, and that's not a problem. What is a problem is that you don't give us enough information to help you.
If you say 'I have a table with two columns, how can I get a searchindex', I'll answer 'read the tutorial and follow the instructions'. After all, they worked for me. Please say in detail what you've done, where you got stuck. 'It doesn't work' is not a good report.

Cheers
Adriano.
Posted Dec 19, 2008 by Adriano Varoli Piazza
 

Comment

12 Input Field side by side

Hello

i've an little Question
I tried to understand the add.ctp from blog tutorial,
so i tried to implement it by myself
/app/views/posts/edit.ctp
    
<h1>Edit Post</h1>
<?php
    
echo $form->create('Post', array('action' => 'edit'));
    echo 
$form->input('title');
    echo 
$form->input('body', array('rows' => '3'));
        echo 
$form->input('id', array('type'=>'hidden')); 
    echo 
$form->end('Save Post');
?>
How can i get the 2 Inputfields side by side not about each other. Is it a thing from the css?

Many greetings

Marcus Radisch
Posted Dec 19, 2008 by Marcus Radisch
 

Comment

13 lesson 2 of posting questions

Hello

i've an little Question
I tried to understand the add.ctp from blog tutorial,
so i tried to implement it by myself
/app/views/posts/edit.ctp
    
<h1>Edit Post</h1>
<?php
    
echo $form->create('Post', array('action' => 'edit'));
    echo 
$form->input('title');
    echo 
$form->input('body', array('rows' => '3'));
        echo 
$form->input('id', array('type'=>'hidden')); 
    echo 
$form->end('Save Post');
?>
How can i get the 2 Inputfields side by side not about each other. Is it a thing from the css?

Many greetings

Marcus Radisch

Ok, now the problem is that you're spamming this tutorial: your question doesn't have anything to do with the subject of the tutorial. Go to http://groups.google.com/group/cake-php and ask the questions there.
But just because I'm nice: $form->input() is very thorough: it creates a div, a label and the input field. Try using just $form->text() and $form->textarea().
Posted Dec 19, 2008 by Adriano Varoli Piazza
 

Comment

14 Thanks

Thanks you for your help to the inputfields. I forgot that it is no forum but a tutorial. im sorry.
Posted Dec 20, 2008 by Marcus Radisch
 

Question

15 Regarding Installation of cakephp

I m new to cakePhp and i don't know how to install cake php please tell me the simple to install cake php i have already installed apache server and mysql and i don't know how to install cakephp in windows can anybody tell me step by step procedure of installition because i can't understand the manual
Posted Dec 20, 2008 by mona
 

Comment

16 no

I m new to cakePhp and i don't know how to install cake php please tell me the simple to install cake php i have already installed apache server and mysql and i don't know how to install cakephp in windows can anybody tell me step by step procedure of installition because i can't understand the manual
You're spamming. This is a tutorial about a search feature to cake, not a general help site. Try not to be so selfish (reading three comments above this, you would have seen this same answer). Go to http://groups.google.com/group/cake-php and ask there, possibly with something better than 'I don't know how to install cakephp'.
Posted Dec 20, 2008 by Adriano Varoli Piazza
 

Comment

17 Simply doesn't work

While it is true that not all programmers can write good tutorials and documentation, IMHO it's articles like this one that gives CakePHP the reputation of having poor documentation. It could and should have been a very useful article but just ended up being frustrating and depressing. At the very least one should have been able to follow it and end up with the advertised conclusion.

I can also write a tutorial that doesn't do what it's suppose to do (i.e. teach) but, like this article, it would not have been useful.

Here ends my bitter frustrated rant.
Posted Jan 1, 2009 by George Davison
 

Question

18 Search return nothing

Good tutorial

I read and practise all this tutorial's steps carrefully and double check it before being sure that search return nothing. I appreciate this, It looks useful way to set search machine on our web specially for cakephp programmer, but in fact the search return nothing.

Is there anybody having success with this? please let me know if there's something wrong or should be fixed in this tutorial.

really thank for you all who make this tutorial more clear and usefull
Posted Jan 5, 2009 by hermawan
 

Comment

19 Thank you

Good idea for a tutorial, having just started with the blog example i found this tutorial to be a welcome addition to my experimentating. Having said that i would like to say that 1 part is unclear, youre not very specific on where to place the search input. Im guessing its in the index.ctp and im probably wrong because when i submit i get the following error:

Error: The requested address '/posts/search' was not found on this server.

edit: I found that setting debug level to 2 removes the error and instead i get the same null string error previously mentioned. Although the posted solution is poorly documented for newbies as well.

edit again: For those running into the same issue: I found the _index() function the solution is referring to as part of the downloaded searchable.php file stored under models/behaviours on line 70.
Posted Jan 16, 2009 by wittedruif
 

Question

20 How do i fetch data from associated tables

Hi,
How do i fetch data from associated tables. One more thing.. when i edit a record does the search index table get updated automatically ...

Regards
Abhishek Jain
Posted Jan 30, 2009 by Abhishek Jain
 

Question

21 Searching in associated tables

Hi,
The example above doesn't search the associated tables.

e.g .. suppose i have 2 tables as
1.listings - id,user_id (e.g 1,1)
2. users - id,name (e.g 1,abhishek)

Now if am looking for all listings by abhishek .. how do i do that search


Thanks in advance

Regards
Abhishek
Posted Jan 30, 2009 by Abhishek Jain
 

Comment

22 errors

i got these errors.. what went wrong?


Query: search
Warning: SQL Error: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'search' at line 1 in /home/jb/Desktop/cakeblog/cake/libs/model/datasources/dbo_source.php on line 439


Fatal error: Call to undefined method FormHelper::create() in /home/jb/Desktop/cakeblog/app/views/posts/search.ctp on line 4


Posted Mar 16, 2009 by zafi
 

Bug

23 feature doesn't work

result array from this tutorial is empty.
Posted Mar 18, 2009 by vislo
 

Question

24 Does it work?

Has anybody got this working? when I click 'Search' it responds with an empty table. Any help would help me out a lot.
Posted Mar 26, 2009 by Gearoid
 

Question

25 Does it work?

Has anybody got this working? when I click 'Search' it responds with an empty table. Any help would help me out a lot.
Posted Mar 26, 2009 by Gearoid
 

Comment

26 Current Data Requires Indexing.


This tutorial does not discuss indexing Current data. To do that please visit:

http://code.google.com/p/searchable-behaviour-for-cakephp/issues/detail?id=1
The second post has a nice example of how to index your current data. Just change the models you want indexed. Execute the page. Voila.

Posted May 19, 2009 by Ryan Barrett
 

Bug

27 Issue with Lastest Build?

I installed this according to the instructions and latest code, but for the "results" array I get data from the "search_index" table instead of from "posts" in my view, so listing post title doesn't work.

Any ideas why?
Posted Aug 26, 2009 by Arash
 

Comment

28 Nice tutorial, thanks muchly

By the way, I didn't know that the search_index table isn't updated until you save your Posts. So any Posts that are in your database before you add the searchable behavior won't actually be searched until you either (a) edit-save each one in turn, or (b) figure out how to index your current data (see 26 Current Data Requires Indexing).
Posted Sep 1, 2009 by Adam
 

Question

29 Warning 512 and 2, what have I done wrong?

Hi, I am admittedly new to CakePHP but have managed to get the blog system working and with pagination. I then expanded the system to handle more data columns but I can't get the search function to work! Instead of Author and Body I now have Address, Move In, Move Out and RSL fields but have kept the table name 'posts'. I get two error messages:

Warning (512): SQL Error: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'search' at line 1 [CORE\cake\libs\model\datasources\dbo_source.php, line 524]

Warning (2): Invalid argument supplied for foreach() [APP\views\posts\search.ctp, line 26]
My index.ctp table matches the search.ctp table. Do I need to add more fields to the search_index table? The foreach section in search reads:


<?php foreach ($results as $post): ?>
    <tr>
        <td><?php echo $post['Post']['id']; ?></td>
        <td><?php echo $post['Post']['moveout']; ?></td>
        <td><?php echo $post['Post']['movein']; ?></td>
        <td><?php echo $html->link($post['Post']['address'],'/posts/view/'.$post['Post']['id']);?></td>
        <td><?php echo $post['Post']['rsl']; ?></td>
        <td><?php echo $post['Post']['notes']; ?></td>
        <td><?php echo $post['Post']['created']; ?></td>
        <td><?php echo $post['Post']['modified']; ?></td>
        <td><?php echo $html->link(
                
'Delete'
                
"/posts/delete/{$post['Post']['id']}"
                
null
                
'Are you sure?'
            
)?>
            <?php echo $html->link('Edit''/posts/edit/'.$post['Post']['id']);?>
        </td>
    </tr>
<?php endforeach; ?>

Any help would be extremely appreciated and thanks for writing this tutorial in the first place!
Posted Sep 11, 2009 by Ben Pawsey
 

Question

30 Search behaviour is providing an empty table?

i am new to cakephp and i have an application wherein i would like to add this search feature. i have gone through these following links provided by you.
http://bakery.cakephp.org/articles/view/search-feature-to-cakephp-blog-example http://code.google.com/p/searchable-behaviour-for-cakephp/ but to no avail. basically i have table or a set of tables with appropriate associations among them. each table have an id and other related fields. some of the tables are admin, profile, country, state etc i have worked with the provided examples but it is returning an empty search_index table?. and i have some questions:

1. what is this association key? is it some kind of id of the tables we need to search?
2. there is a field association key provided in the tables but it has a different datatype in the two examples. why and which one would be correct.
3. what procedure should i employ to make the search work?
4. what customizations do i need to put in?
5. table: admin - id, fname(e.g 1,rahul)
state - id,admin_id (e.g 1,1)
locality - id, admin_id (e.g 1,1)
how do i get search for rahul in state-1 and locality-1 and how to search from associted tables of admin?
6. moreover after this text search feature i'm looking for a dropdown search feature using ajax. it would provide results after filtering the country, state, locality dropdown menus. please provide some tutorials, or elements, behaviour, plugins. any kind of help would be highly appreciable.
thanx & regards
rahul
Posted Oct 15, 2009 by RAHUL GUPTA
 

Comment

31 How to get associated data

In the controller change this:
 <?php
  $this
->set('results',$this->Post->search($this->data['Post']['q'])); 
?> 

to this:

<?php
  $this
->set('results',$this->Post->search($this->data['Post']['q'], array('recursive' => 2))); 
?> 

As you can see, you can use the same options for "find" method as second parameter for search method.

In this example you will obtain the associated data to your Post model, in the result you will have 3 models (SearchIndex, Post and a associated model to post)

=).

great tutorial, thanks!
Posted Nov 18, 2009 by Ignacio Daniel Casas
 

Comment

32 Empty search results

Becuase the behaviour only adds data after its been installed.

There are some functions below for having all existing data added into the search index.

http://code.google.com/p/searchable-behaviour-for-cakephp/issues/detail?id=1
Posted Dec 30, 2009 by Danno
 

Question

33 Still getting empty result set

Thanks for this tutorial, it was helpful.

For those who are getting empty results sets, I've just realised that it's because the search code creates an index table for itself, which it populates as you add and modify pages on the site. This means that any pages which were on the site when you added the search code won't be searched on - so you'll need to modify them or add new ones.
Posted Jan 7, 2010 by Sharon
 

Comment

34 SQL error with search.

I am getting a SQL error: "....right syntax to use near 'search' at line...". I put the search_index.php file in models and the searchable.php in models/behaviors, but i don't know what going on. can somesone please help
Posted Jan 19, 2010 by ngoni
 

Comment

35 'association_key' cannot be null

I am using this behavior on two different models (User and Post). It is working fine when I add a new user or when I search posts or users but when I try to add a new post I get the following errors.
Undefined index: User [APP/models/behaviors/searchable.php, line 77] Invalid argument supplied for foreach() [APP/models/behaviors/searchable.php, line 78] SQL Error: 1048: Column 'association_key' cannot be null [CORE/cake/libs/model/datasources/dbo_source.php, line 525] Query: INSERT INTO `search_index` (`model`, `association_key`, `data`, `modified`, `created`) VALUES ('User', NULL, '', '2010-02-28 12:04:11', '2010-02-28 12:04:11')

Query: INSERT INTO `search_index` (`model`, `association_key`, `data`, `modified`, `created`) VALUES ('User', NULL, '', '2010-02-28 12:04:11', '2010-02-28 12:04:11')

Cannot modify header information - headers already sent by (output started at /home/xxx/example.com/cake/basics.php:307) [CORE/cake/libs/controller/controller.php, line 644]
So from what I can tell when I add a post something with the user model is conflicting with my add posts function. I would expect to see the query values start with the 'Post' model then the post id and then some data.

Is there something I need to do when using this behavior on two different models?
Posted Feb 28, 2010 by Foroct Fralion
 

Comment

36 recursive

I have recursive set to -1 in my AppModel and the code didn't work.
Adding var $recursive = 1;  to the SearchIndex model fixed the problem.
Posted Mar 4, 2010 by timmay
 

Comment

37 Nice Post.

indeed, $error is not set in that piece. Sohbet but that's intentional, Chat as the view will never Muhabbet be rendered. (if that if statement is true, Cinsel Sohbet offcourse)

Hence the $this->redirect in the code, Lez Sohbet and the return statement Bayan Chat (that you left out in your Bayan Sohbet copy-paste, Almanya Chat but it's in the original ;-) Arkadaş Sohbet This will make sure the view will Porno Sohbet not be rendered, Diyarbakır Sohbet and you will be redirected. Lez That's why you don't need to "prepare" Mirc indir the view by setting variables for it.
Posted Mar 19, 2010 by Metin