Troy Thompson

Web Developer

Archive for the ‘mysql’ Tag

  1. Searching on Multiple Fields in CakePHP

    Published
    Last Updated
    May 04 2008
    Tagged
    Content

    Lets say you want to provide users with a way to search for authors in CakePHP.

    Your authors table looks something like ( id, firstname, lastname, bio ).

    Usually when you want to search on something like this you would do the following.

    SELECT * FROM authors WHERE lname LIKE '%Jon%' OR lname LIKE '%Jon%';

    Great, you found Jon, but what if you replaced the above query with "Jon Doe"?

    SELECT * FROM authors WHERE lname LIKE '%Jon Doe%' OR lname LIKE '%Jon Doe%';

    Crap, we can't find Jon anymore. Okay how about the following:

    SELECT * FROM authors WHERE concat(fname,' ',lname) like '%Jon Doe%';

    Aha! We found Jon Doe again.

    But what if we searched for "Doe Jon". Again, we are not able to find Jon Doe.

    So now what? Well MySQL lets you build a fulltext index on multiple fields.
    Execute the following query.

    ALTER TABLE `authors` ADD FULLTEXT `fullname` (`fname`,`lname`);

    This allows us to do things like

    SELECT * FROM authors WHERE match(fname,lname) against ('doe jon' IN BOOLEAN MODE);

    And still get Jon Doe. :-)

    Now you can fight this fulltext search stuff all you want, but you're just going to end up with a huge query that doesn't perform as well as a fulltext query.

    If you have a database that does not support this, then you should consider upgrading if you can.
    Here is some code that creates a query that does a search on each field without fulltext indexing.

    Using a fulltext query in CakePHP is a matter of using the following condition ( yes, this is very hacky looking ):

    $paginator_options['conditions'] = array("1" => "1 AND MATCH(Author.fname,Author.lname) AGAINST('{$conditions['Author.search']}*' IN BOOLEAN MODE )");
    $this->set('authors', $this->paginate($paginator_options));