CakePHP Fulltext search MySQL with rating

2019-05-22 23:16发布

问题:

I've read that, to be able to rank search results you may query MySQL like this:

SELECT * , 
MATCH (title, body) AGAINST ('$search') AS rating 
FROM posts 
WHERE MATCH (title, body) AGAINST ('$search') 
ORDER BY rating DESC

Is there a way to do this in CakePHP 2.X? Also, I need to do this while paginating at the same time. So I think I would need to write condition for the paginator, not a direct 'query'.

Thanks for your help!

回答1:

Use like this it will prevent mysql injection too

array("MATCH(User.current_position) AGAINST(? IN BOOLEAN MODE)" => $srch_arr['text'])


回答2:

Ok, it took me some time... Since, the key issue was to get a rating on the resulting matches, the complicated part in this query was the specific field:

MATCH (title, body) AGAINST ('$search') AS rating

I figured that I should just write that field in the "field" option, in the pagination array. The resulting code was the following:

    $this->paginate = array(
            'limit' => 15,
            'fields' => array('*', "MATCH (data) AGAINST ('$q') AS rating"),
            'conditions' =>  "MATCH(SearchIndex.data) AGAINST('$q' IN BOOLEAN MODE)",
            'order' => array(
                'rating' => 'desc',
            ),
    );
    $paginatedResults = $this->paginate('SearchIndex');

And that worked seamlessly!

I think this is the best way to achieve real search results using Cake. Unless someone has a better alternative :)

Searching phrases in between double quotes will give you the results you should expect!



回答3:

I have used the above database call by Thomas (thank you) and it does work seamlessly.

However the code:

'conditions' =>  "MATCH(SearchIndex.data) AGAINST('$q' IN BOOLEAN MODE)",

removes the Data Abstraction Layer and opens up your site to SQL injection.

It's probably not quite as good (haven't fully tested it) but try:

'SearchIndex.data LIKE'=>'%'.$search.'%'

I hope this is helpful in someway.