社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  DATABASE

百度二面,MySQL 怎么做权重搜索?

程序员好物馆 • 8 月前 • 219 次点击  

作者 | 小牛肉

来源 | 飞天小牛肉

考虑这样一个搜索需求,有一个 MySQL 表,表中很多个列存放着不同的内容,希望用户通过关键词进行搜索的时候,能够模糊匹配多个列,比如有 t1 列、t2 列、t3 列,同时还希望 t1 列的匹配权重最高,t3 列的匹配权重最低。简单说就是如果有一个关键词同时出现在记录 A 的 t1 列 和里记录 B 的 t2 列,那么记录 A 应该优先展示,排序是在前面的。

注意这里是 MySQL,不是 ES,搜索引擎做这种搜索需求当然得天独厚,但是这种在 MySQL 中进行权重搜索的需求也不是没有,业务初期数据量还不大的时候大概率不会考虑上 ES,这时候在 MySQL 中先简单跑通逻辑才是最重要的。

思考下该如何做?

模糊匹配

首先模糊匹配大家最常用的就是 like

SELECT * FROM test 
WHERE t1 LIKE '%标题%' 
 or t2 LIKE '%内容%' 
 or t3 LIKE '%注释%''
当只需要简单的模式匹配时 like 确实往往是更好的选择。而在需要进行复杂匹配,如同一字段中包含多个模式,进行分组匹配等,REGEXP 则表现更为突出,Mysql 支持对列的正则表达式方式查询,使用方式如下:
SELECT  * FROM test 
WHERE t1 regexp '标题'
 or t2 regexp '内容' 
 or t3 regexp '注释'

权重搜索

权重搜索涉及到几个 Mysql 函数。

  • LOCATE('标题', test.t1) :查询 "标题" 在 test.t1 列出现的位置,0 表示未找到。否则返回 坐标位置,坐标位置从 1 开始。

  • IF( 表达式, 1, 0):判断表达式结果,TRUE 则返回 1,FALSE 则返回 0

下面我们来看如何基于这两个函数来实现文章开头的需求:

SELECT  *, ( 
    IF(LOCATE('标题',test.t1), 10
     + IF(LOCATE('内容',test.t2) , 10
     + IF(LOCATE('注释',test.t3) , 10
 ) AS weight 
FROM test 
WHERE test.t1 regexp '标题'
 or test.t2 regexp '内容' 
 or test.t3 regexp '注释' 
order by weight desc 

上面的查询中,每个关键词的权重都是 1,所以,在这 t1\t2\t3 三列中,关键词出现次数最多的记录将出现在搜索结果的第一位。

如果权重增加,那么权重高的关键词将会影响排序规则。如下例子,将 t1 列的搜索权重改为 7:
SELECT  *, ( 
    IF(LOCATE('标题',test.t1), 70
     + IF(LOCATE('内容',test.t2) , 20
     + IF(LOCATE('注释',test.t3) , 10
 ) AS weight 
FROM test 
WHERE test.t1 regexp '标题'
 or test.t2 regexp '内容' 
 or test.t3 regexp '注释' 
order by weight desc 


好啦,今天的内容分享就到这,感觉不错的同学记得分享点赞噢!
PS:程序员好物馆 持续分享程序员学习、面试相关干货,不见不散!
点分享
点收藏
点点赞
重点看

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/175747
 
219 次点击