CakePHP Fulltext search MySQL with rating

2019-05-22 23:52发布

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!

3条回答
我想做一个坏孩纸
2楼-- · 2019-05-22 23:57

Use like this it will prevent mysql injection too

array("MATCH(User.current_position) AGAINST(? IN BOOLEAN MODE)" => $srch_arr['text'])
查看更多
走好不送
3楼-- · 2019-05-23 00:09

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!

查看更多
beautiful°
4楼-- · 2019-05-23 00:19

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.

查看更多
登录 后发表回答