简体   繁体   中英

CakePHP find query using %like%

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 

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
        )
    )
);

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%"
        )
    )
);

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.

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."%"
        )
    )
);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM