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
To view records of database, we first need to get hold of a table using the TableRegistry class. We can fetch the instance out of registry using get() method. The get() method will take the name of the database table as argument. Now, this new instance is used to find records from database using find() method.
Add below line in your model where you want print query. $last_query = $ this ->ModelName->getLastQuery(); As we have saved last executed query in variable $last_query then use this to print last executed query.
To apply ordering, you can use the order method: $query = $articles->find() ->order(['title' => 'ASC', 'id' => 'ASC']); When calling order() multiple times on a query, multiple clauses will be appended.
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
)
)
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With