使用ES+云开发实战优化网站搜索大家好,我是鱼皮
云开发实战优化网站搜索1,带大家优化网站搜索的灵活性。网站搜索优化背景个月了,但是从上线之初,网站一直存在一个很严重的问题,就是搜索功能并不好用。此前,为了追求快速上线,搜索功能就简单地使用了数据库模糊查询(包含)来实现
在实践中使用ES+云开发优化网站搜索
大家好,我是于皮。 今天我就来进行一场技术实战。 需求分析=>技术选型=>设计与实现,从0到1,帮助您优化网站搜索的灵活性。
ES+云开发搜索优化实践
本文大纲:
鱼皮-网站搜索优化背景
我开发的编程导航网站已经上线6个月了,但是从一开始,网站就出现了一个严重的问题,那就是搜索功能不太好用。
此前网站的优化,为了追求快速上线,搜索功能只是简单地利用数据库模糊查询(含)来实现。 这样虽然方便开发,但是这种方式非常不灵活。
例如,网站上有一个名为“Java ”的资源,但用户搜索“Java ”时找不到任何内容。 原因是资源名称中包含空格,而用户搜索时输入的关键字不包含空格。
空间只是一个特例,类似的情况还有很多。 例如,网站上有一个资源叫《Java并发编程实践》,但是当用户搜索“Java实践”时,明明前者包含“Java”和“实践”两个词,却什么也没有。成立。
要知道,搜索功能对于一个信息聚合网站来说至关重要,直接影响用户体验。 如果我在您的网站上找不到资源,谁会使用它们?
所以我也收到了一些朋友的礼貌建议,比如这个光头汤姆:
之前没有优化搜索,主要有两个原因:穷+怕麻烦。 但随着网站用户数量的增加,是时候填补空白了!
技术选型
如果想提高网站搜索的灵活性,可以使用全文搜索技术,该技术在前端和后端都可以实现。
前端全文检索
有时,我们要检索的数据是有限的,所有数据都存储在客户端。
例如,在个人博客网站上,我们通常将每篇文章作为文件存储在某个目录中,而不是存储在后端数据库中。 这样的话,就不需要向服务器请求动态数据,直接在前端查找数据即可。 。
有一些现成的搜索库,例如(7k+ star)。 首先添加要检索的内容:
然后只需搜索:
纯前端全文检索的优点是不需要后端,简单方便,可以节省服务器的压力; 无需连接互联网,没有额外的网络开销,检索速度更快。
后端全文检索
与前端不同的是,后端全文检索是在服务器上完成的,从远程数据库中查找符合要求的数据,然后直接返回给前端。
目前主流的后端全文搜索技术是分布式、风格搜索和数据分析引擎。
它功能强大,灵活,但是需要自己搭建,定义数据,管理字典,上传和维护数据等,可操作性很强,需要一定的熟练程度。 新手设计的ES搜索系统和专家设计的ES搜索系统存在巨大差异。 。
因此,不熟悉的同学也可以直接使用现成的全文检索服务。 例如,您可以通过它提供的API直接上传您需要检索的数据,然后使用它提供的API进行检索。 它提供了一定的可用空间,对于小型网站和学习来说完全足够了。
搜索服务选择
那么我的编程导航网站应该选择哪种实现方式呢?
首先,该网站的资源数量不固定,不定期动态更新,因此不适合前端全文检索。
其次,考虑到未来网站的数据量会比较大,而且搜索系统(比如自定义编程词典)可能需要根据用户搜索进行动态优化,可以考虑用技术来构建自己的搜索引擎而不是使用现成的全文搜索服务。 ,以便您将来可以随心所欲地定制系统。 另外,无需将网站数据发送到其他平台,保证了数据安全。
ES安装
确认使用后,首先要搭建环境。
您可以自行购买服务器,按照官方文档一步步手动安装。 对于有一定规模的个人网站来说,虽然建立过程并不困难,但是后期的维护成本却是巨大的,比如性能分析、监控、报警、安全等,都需要自己去配置。 尤其是后期网站数据量变大的时候,我们需要考虑搭建集群、横向扩展等。
因此,我选择直接使用云服务商提供的服务。 这里我选择腾讯云,它会自动为你搭建现成的ES集群服务。 还提供可视化架构管理、集群监控、日志、高级插件、智能巡检等功能。
云ES集群架构图
ES服务虽然价格昂贵,但是节省了大量的时间和成本,这对我来说是值得的。
还有一个非常方便的定制搜索服务应用程序。 如果你有兴趣,可以尝试一下。
公共服务
我们的目标是优化网站资源的搜索功能,但接下来要做的不是直接写具体的业务逻辑,而是先开发一个公共ES服务。
其实ES的操作还是比较简单的。 你可以简单的把它理解为一个数据库。 那么公共ES服务应该具备基本的增删改查功能,供其他函数调用。
完成
由于编程导航后端采用腾讯云开发技术,使用Node.js编写服务,因此使用官方推荐的库来操作ES。
如果您以前没有使用过云开发也没关系。 你可以先把它理解为后端。 欢迎阅读我之前的文章:了解云开发。
代码非常简单。 首先,与ES建立连接。 为了保证数据安全,这里使用内网地址:
然后写增删改查。 这里进行了一步抽象,通过分支语句根据请求参数区分操作、要操作的数据等,这样每个操作就不需要独立写成一个接口了。
在云开发中,如果某个函数长时间没有被调用,就会释放资源。 下次请求时,会进行冷启动,重新创建资源,导致界面返回缓慢。 因此,将多个操作封装到同一个函数中也可以减少冷启动的机会。
代码的具体增删改查我就不细说了。 直接看ES Node的官方文档就可以了。 代码稍后会开源给编程导航仓库()。
本地调试
编写完代码后,可以使用云开发自带的命令行工具在本地执行该功能。
记得先把ES的连接地址改成公网,然后输入一行命令。 比如我们要向ES中插入一条数据,传入函数名、请求参数、要执行的代码路径:
执行成功后,可以在ES中看到新插入的数据(通过面板或者curl查看):
远程测试
本地测试公共服务代码后,将ES连接地址更改为内网IP,然后发布到云端。
接下来尝试编写另一个函数来访问公共ES服务,例如通过请求向ES中插入资源:
但是数据并没有插入成功,而是返回了接口超时。 为什么?
内网配置
从日志中发现ES无法连接。 难道是因为ES公共服务发布的机器和ES不在同一个内网?
因此,您需要在云开发控制台修改ES公共服务的私网配置。 只需选择与购买ES时相同的子网即可:
配置ES云功能私网
修改完成后,再次远程请求ES公共服务,数据就插入成功了~
数据索引
开发完ES公共服务后,就可以编写具体的业务逻辑了。
首先,需要在ES中创建索引(类似于数据库表),约定数据类型、分词等信息,而不是允许随机插入数据。
例如,为了更灵活的搜索,应将资源名称指定为“text”类型以启用分词,并指定中文分词:
点赞数应设置为“long”类型,且只允许传入数字:
另外最好为索引指定一个别名,方便后续修改字段时重建索引:
写完索引的json配置后,只需通过curl或调用ES新建索引接口即可。
数据同步
此前,编程导航网站的资源数据存储在数据库中,用户从数据库中查询。 但现在我们想从ES查询。 ES 是否为空也没关系。 我们得想办法把数据库中的资源数据同步到ES上。
这里有几种同步策略。
双写
过去,用户推荐的资源只是插入到数据库中。 双写是指资源插入数据库时,同时插入到ES中。
听起来很简单,但是这种方法存在一些问题:
之前的代码会改一下,凡是写数据库的地方都会加上ES。
可能会出现一侧写入失败,另一侧写入成功的情况,导致数据库和ES数据不一致。
那么有没有一种对现有代码侵入性较小的方法呢?
定时同步
如果对数据实时性要求不高,可以选择定时同步,定期将数据库中最新插入或修改的数据复制到ES中。
实现的方式有很多种,比如使用数据传输管道,或者自己写一个定时任务程序,所以根本不需要改变现有的代码。
实时同步
如果对数据的实时性要求非常高,刚插入数据库的数据必须能够立即被检索到,那么就需要实时同步。 除了双写之外,还可以监控数据库。 我们将了解数据库中的任何更改。
阿里巴巴有一个开源项目叫,可以实时监控MySQL数据库,并向下游用户推送通知。 有兴趣的朋友可以看看。
运河工程实施
由于搜索编程资源对实时性要求不高,所以定期同步就可以了。
云开发默认提供了定时功能功能。 我直接写了一个云函数网站的优化,每1分钟执行一次,每次读取数据库中过去5分钟变化的数据,防止上次执行失败。 另外,必须配置超时时间,防止函数执行时间过长导致执行失败。
云开发中——云功能控制台可以可视化配置。 您需要为计划任务指定一个表达式:
配置云函数定时和超时
开启定时同步后,不要忘记编写并执行第一个同步函数,将所有历史数据同步到ES。
数据检索
现在ES上有了数据,就只剩下最后一步了,就是如何查找数据呢?
首先我们需要学习ES的搜索DSL(语法),包括如何获取列、搜索、过滤、分页、排序等,对于新手来说还是有点麻烦,尤其是查询中布尔表达式的组合条件一不注意的话。 找不到数据。 因此,建议您先在提供的调试工具中编写查询语法:
调试
找到想要的数据后,编写后端搜索功能。 接受的请求参数最好与原来的接口保持一致,以减少改动。
查询语法可以根据前端的请求动态拼接。 例如,如果您想按资源名称搜索:
至此,整个网站的搜索优化就完成了。
我们再试一下效果。 现在即使我输入一些“鱼”字,我也能找到它!
ES是如何实现灵活搜索的? 欢迎阅读这篇文章。
新的ES搜索接口的发布并不意味着旧的数据库查询接口被淘汰,同时可以保留。 按名称搜索资源时,使用新的界面,更加灵活; 根据评论状态查找用户发布的资源时,可以使用旧界面从数据库中查找。 这样,负载被分担,责任被分离,正确的技术才能做正确的事!