Home » Php » php – CakePHP find query using %like%

php – CakePHP find query using %like%

Posted by: admin July 12, 2020 Leave a comment

Questions:

I have the following find query for my CakePHP app:

$this->paginate = array(
'limit'=>5,
'order'=>'Note.datetime DESC',
'conditions' => array(
    'Note.status'=>1,
    'OR' => array(
        'Note.title LIKE' => '%'. $q . '%',
        'Note.content LIKE' => '%'. $q . '%'
        )
    )
);

Which takes a parameter called $q to do like query on both title and content.

So for example if I have the following:

Title: Lorem ipsum
Content: Lorem ipsum dolare

And search for 'lorem'

It would find it fine. But if I search for 'lorem dolare' it won’t find it.

How do I do that?

Note: I don’t want to use any plugins etc.

EDIT: If I use FULLTEXT would this work?

$this->paginate = array(
'limit'=>5,
'order'=>'Note.datetime DESC',
'conditions' => array(
    'Note.status'=>1,
    'OR' => array(
        'MATCH(Note.title) AGAINST('.$q.' IN BOOLEAN MODE)',
        'MATCH(Note.content) AGAINST('.$q.' IN BOOLEAN MODE)'
        )
    )
);

EDIT 2:

Getting this error trying the above:

 Error: SQLSTATE[42000]: Syntax error or access violation: 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 'dolor IN BOOLEAN MODE)) OR (MATCH(`Note`.`content`) AGAINST(lorem dolor IN BOOLE' at line 1

SQL Query: SELECT `Note`.`id`, `Note`.`title`, `Note`.`excerpt`, `Note`.`content`, `Note`.`datetime`, `Note`.`user_id`, `Note`.`slug`, `Note`.`status`, `Note`.`topic_id`, `User`.`id`, `User`.`email`, `User`.`firstname`, `User`.`lastname`, `User`.`password`, `User`.`status`, `Topic`.`id`, `Topic`.`title`, `Topic`.`slug` FROM `db52704_driz2013`.`notes` AS `Note` LEFT JOIN `db52704_driz2013`.`users` AS `User` ON (`Note`.`user_id` = `User`.`id`) LEFT JOIN `db52704_driz2013`.`topics` AS `Topic` ON (`Note`.`topic_id` = `Topic`.`id`) WHERE `Note`.`status` = 1 AND ((MATCH(`Note`.`title`) AGAINST(lorem dolor IN BOOLEAN MODE)) OR (MATCH(`Note`.`content`) AGAINST(lorem dolor IN BOOLEAN MODE))) ORDER BY `Note`.`datetime` DESC LIMIT 5 
How to&Answers:

Try this

$this->paginate = array(
    'limit'=>5,
    'order'=>'Note.datetime DESC',
    'conditions' => array(
        'Note.status'=>1,
        'OR' => array(
            "MATCH(Note.title) AGAINST('".$q."' IN BOOLEAN MODE)",
            "MATCH(Note.content) AGAINST('".$q."' IN BOOLEAN MODE)"
        )
    )
);

In other words, enclose the search criteria with quotes

EDIT ndm’s suggestion makes sense

$this->paginate = array(
    'limit'=>5,
    'order'=>'Note.datetime DESC',
    'conditions' => array(
        'Note.status'=>1,
        'OR' => array(
            'MATCH(Note.title) AGAINST(? IN BOOLEAN MODE)' => $q,
            'MATCH(Note.content) AGAINST(? IN BOOLEAN MODE)' => $q
        )
    )
);

Answer:

You can also try this:

$this->paginate = array(
    'limit'=>5,
    'order'=>'Note.datetime DESC',
    'conditions' => array(
        'Note.status'=>1,
        'OR' => array(
            'Note.title LIKE' => "%$q%",
            'Note.content LIKE' => "%$q%"
        )
    )
);

Answer:

LIKE won’t help you here. Your title is Lorem ipsum and your content is Lorem ipsum dolare. You’re searching for lorem dolare, which won’t be found via the LIKE operator as it is not a substring inside either of those columns. You’ll need to look into using FULLTEXT or you’ll need to use something like Sphinx. Take a look at this answer here if you’re trying to figure out what solution to implement.

Answer:

Please Try this:

$this->paginate = array(
    'limit'=>5,
    'order'=>'Note.datetime DESC',
    'conditions' => array(
        'Note.status'=>1,
        'OR' => array(
            'Note.title LIKE' => "%".$q."%",
            'Note.content LIKE' => "%".$q."%"
        )
    )
);