怎么用Redis实现搜索接口


对于后端开发人员来讲使用一条sql就可以实现列表查询的接口,如果查询条件很复杂,表库设计不合理,会导致查询很困难,这篇文章和大家分享一下用redis实现搜索接口。

下面以一个例子开始,这是某购物网站的搜索条件,如果让你实现这样的一个搜索接口,你会如何实现?

当然你说借助搜索引擎,像 Elasticsearch 之类的,你完全可以实现。但我这里想说的是,如果要你自己实现呢?

怎么用Redis实现搜索接口

从上图中可以看出,搜索总共分为 6 大类,每大类中又分了各个子类。

在这种情况下,筛选过程取各大类条件的交集,并考虑各子类中单选、多选和自定义的情况,以输出符合条件的结果集。

好了,既然需求很明确了,我们就开始来实现。

实现 1

率先登场是小 A 同学,他是写 SQL 方面的“专家”。小 A 信心满满的说:“不就是一个查询接口吗?看着条件很多,但凭着我丰富的 SQL 经验,这点还是难不倒我的。”

于是乎就写出了下面这段代码(这里以 MySQL 为例):

select ... from table_1 
left join table_2 
left join table_3 
left join (select ... from table_x where ...) tmp_1 
... 
where ... 
order by ... 
limit m,n

代码在测试环境跑了一把,结果好像都匹配上了,于是准备上预发。这一上预发,问题就开始暴露出来。

预发为了尽可能的逼真线上环境,所以数据量自然而然要比测试大的多。所以这么一个复杂的 SQL,它的执行效率可想而知。测试同学果断把小 A 的代码给打了回来。

实现 2

总结了小 A 失败的教训,小 B 开始对 SQL 进行了优化,先是通过了 explain 关键字进行 SQL 性能分析,对该加索引的地方都加上了索引。

同时将一条复杂 SQL 拆分成了多条 SQL,计算结果在程序内存中进行计算。

伪代码如下:

$result_1 = query('select ... from table_1 where ...'); 
$result_2 = query('select ... from table_2 where ...'); 
$result_3 = query('select ... from table_3 where ...'); 
... 
 
$result = array_intersect($result_1, $result_2, $result_3, ...);

这种方案从性能上明显比第一种要好很多,可是在功能验收的时候,产品经理还是觉得查询速度不够快。

小 B 自己也知道,每次查询都会向数据库查询多次,而且有些历史原因,部分条件是做不到单表查询的,所以查询等待的时间是避免不了的。

实现 3

小 C 从上面的方案中看到了优化的空间。他发现小 B 在思路上是没问题的,将复杂条件拆分,计算各个子维度的结果集,最后将所有的子结果集进行一个汇总合并,得到最终想要的结果。

于是他突发奇想,能否事先将各个子维度的结果集给缓存起来,这要查询的时候直接去取想要的子集,而不用每次去查库计算。

这里小 C 采用 Redis 来存储缓存数据,用它的主要原因是,它提供了多种数据结构,并且在 Redis 中进行集合的交并集操作是一件很容易的事情。

具体方案,如图所示:

怎么用Redis实现搜索接口

这里每个条件都事先将计算好的结果集 ID 存入对应的 Key 中,选用的数据结构是集合(Set)。

查询操作包括:

    • 子类单选:直接根据条件 Key,获取对应结果集。

    • 子类多选:根据多个条件 Key,进行并集操作,获取对应结果集。

    • 最终结果:将获取的所有子类结果集进行交集操作,得到最终结果。

这其实就是所谓的反向索引。这里会发现,漏了一个价格的条件。从需求中可知,价格条件是个区间,并且是无穷举的。

SOAP语法 word版 SOAP语法 word版

SOAP、WSDL(WebServicesDescriptionLanguage)、UDDI(UniversalDescriptionDiscovery andIntegration)之一, soap用来描述传递信息的格式, WSDL 用来描述如何访问具体的接口, uddi用来管理,分发,查询webService 。具体实现可以搜索 Web Services简单实例 ; SOAP 可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议(HTTP),简单邮件传输协议(SMTP),多用途网际邮件扩充协议

SOAP语法 word版 0 查看详情 SOAP语法 word版

所以上述的这种穷举条件的 Key-Value 方式是做不到的。在此处,我们使用了 Redis 的有序集合(Sorted Set)这一数据结构进行了实现

怎么用Redis实现搜索接口

将所有商品加入 Key 为价格的有序集合中,值为商品 ID,每个值对应的分数为商品价格的数值。

这样在 Redis 的有序集合中就可以通过 ZRANGEBYSCORE 命令,根据分数(价格)区间,获取相应结果集。

至此,方案三的优化已全部结束,将数据的查询与计算通过缓存的手段,进行了分离。

在每次查找时,只需要简单的查找 Redis 几次就能得出结果。查询速度上符合了验收的要求。

扩展

①分页

这里你或许发现了一个严重的功能缺陷,列表查询怎么能没有分页。是的,我们马上来看 Redis 是如何实现分页的。

分页主要涉及排序,这里简单起见,就以创建时间为例。如图所示:

怎么用Redis实现搜索接口

图中蓝色部分是以创建时间为分值的商品有序集合,蓝色下方的结果集即为条件计算而得的结果,通过 ZINTERSTORE 命令,赋结果集权重为 0,商品时间结果为 1,取交集而得的结果集赋予创建时间分值的新有序集合。

对新结果集的操作即能得到分页所需的各个数据:

    • 页面总数为:ZCOUNT 命令。

    • 当前页内容:ZRANGE 命令。

    • 若以倒序排列:ZREVRANGE命令。

②数据更新

关于索引数据更新的问题,有两种方式来进行。一种是通过商品数据的修改,来即时触发更新操作,一种是通过定时脚本来进行批量更新。

这里要注意的是,关于索引内容的更新,如果暴力的删除 Key,再重新设置 Key。

因为 Redis 中两个操作不会是原子性进行的,所以中间可能存在空白间隙,建议采用仅移除集合中失效元素,添加新元素的方式进行。

③性能优化

Redis 是内存级操作,所以单次的查询会很快。但是如果我们的实现中会进行多次的 Redis 操作,Redis 的多次连接时间可能是不必要时间消耗。

通过使用 MULTI 命令,开启一个事务,将 Redis 的多次操作放在一个事务中,最后通过 EXEC 来进行原子性执行。

注意:这里所谓的事务,只是将多个操作在一次连接中执行,如果执行过程中遇到失败,是不会回滚的。

总结

这里只是一个采用 Redis 优化查询搜索的一个简单 Demo,和现有的开源搜索引擎相比,它更轻量,学习成本页相应低些。

其次,它的一些思想与开源搜索引擎是类似的,如果再加上词语解析,也可以实现类似全文检索的功能。

以上就是怎么用Redis实现搜索接口的详细内容,更多请关注其它相关文章!


# 上了  # 相城网站建设选哪家  # 运城专业的网站建设  # SEO目标近期  # 网站建设专业招聘  # 淄博网站seo多少钱  # 江苏短视频营销推广免费试用  # 建设银行网站登录不了  # 伊春关键词竞价排名  # wordpress seo导航主题  # 云狐seo基础知识  # redis  # 多个  # 进行了  # 这一  # 穷举  # 的是  # 如何实现  # 分页  # 数据结构  # 子类 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: 《画加》约稿流程  Git命令与VS Code UI操作的对应关系解析  TikTok网页版入口快速访问 TikTok官网账号登录方法  263企业邮箱如何设置邮件转发功能  响应式设计中动态背景颜色条的实现指南  使用Python和GBGB API高效抓取指定日期范围和赛道比赛结果教程  VB表达式书写规则解析  《美篇》取消会员自动续费方法  在Spring Boot Thymeleaf中利用布尔属性实现容器的条件显示  支付宝如何解绑云闪付_支付宝与云闪付账户关联解除方法  冬季去寒冷地区旅游,以下哪种做法有助于缓解冻伤  解决SQLAlchemy模型跨文件关联的Linter兼容性指南  汽水音乐车机版 汽水音乐车机版官方入口  realme 10 Pro息屏方案_realme 10 Pro省电策略  《猎聘》筛选猎头岗位方法  C++ optional用法详解_C++17处理可能为空的返回值  ExcelSCAN与LAMBDA如何创建自定义移动平均函数_SCAN实现任意窗口期移动平均计算  火柴人战争网页版在线玩  Apple Music无故扣费引质疑  《随手记》关闭首页消息推送方法  百度网盘如何设置上传限额  《饿了么》拼好饭点外卖教程2025  qq邮箱怎么注册_QQ邮箱注册步骤与注意事项  电脑桌面图标怎么变大变小_Windows个性化设置第一课【新手入门】  Flexbox布局中Stencil组件宽度不显示问题解析与:host尺寸控制  《下一站江湖2》大雪山加入方法  sf漫画官网登录入口直达_sf漫画官方正版网址  海棠书屋官方在线书籍入口 海棠书屋文学作品浏览官网链接  c++如何实现观察者设计模式_c++行为型设计模式实战  追剧达人如何发弹幕  163邮箱网页版官方登录入口 163邮箱网页版访问页面  C++ switch case字符串_C++如何实现字符串switch匹配  口腔诊所管理软件推荐  泰拉瑞亚水晶无法放置问题  Word如何将文字快速转成表格 Word文本转换成表格功能使用技巧【效率】  抖音号升级成企业资质怎么弄?有什么好处?  研招网官方网站正版登录网址_中国研究生招生信息网官网首页  AI图层蒙版怎么用_AI图层蒙版应用技巧与设计实例  Mac hosts文件在哪里_Mac修改hosts文件详细教程  cad加载的线型看不见怎么办_cad线型不可见问题解决方法  《友玩*》创建群聊方法  如何在Podman容器中运行Composer_Docker替代品Podman的PHP与Composer容器化实践  Bootstrap 5导航栏折叠功能失效:数据属性迁移指南  微信注销后银行卡解绑了吗_微信注销后银行卡解绑状态  《波斯王子:失落的王冠》剑术大师打法攻略  word邮件合并怎么插入个性化图片_Word邮件合并插入个性化图片方法  Highcharts雷达图径向轴数值标签实现教程  手机耗电快是什么原因 延长手机电池续航时间的设置方法【详解】  使用TinyButStrong生成HTML并结合Dompdf创建PDF教程  易车网官网直达入口 易车网在线登录入口 

 2023-06-02

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.