纯MongoDB实现中文全文搜索

查询词预处理

因为我们针对二元分词的结果做搜索,所以无法直接搜索。以为例,二元分词的全文索引里根本没有三个字的词,是搜索不出来结果的,必须转换成短语””这样才能匹配上,所以要对查询词作预处理:进行二元分词,并用双引 约束位置,这样才能正确查询。

如果有多个查询词或带有反向查询词,则需要作相应的处理,在此仅以独词查询示例,具体不用细述。

MongoDB不仅支持在中使用全文搜索,也可在中使用,在中使用是差不多的,不过要留意的是只能在第一阶段使用带的。

初步结果

首先值得肯定的是做了简单的二元分词处理之后,纯MongoDB就能够实现中文全文搜索,搜索结果是精准的,没有错搜或漏搜的情况。

不过在性能上比较差强人意,在约4000万文档的集合中,搜索牛仔裤需要10秒钟以上。而且在项目的使用场景中,我们发现用户实际查询的词很长,往往是直接在电商平台复制商品名的一部分,甚至全部,这种极端情况需要几分钟才能得到查询结果。

在产品层面,可以对用户查询的词长度进行限制,比如最多3个词(即2个空格)且总长度不要超过10个汉字(或20个字母,每汉字按两个字母计算),这样可以控制相对快一点。但这样的规则不容易让用户明白,用户体验受损,需要想办法优化性能。

优化

结巴中文分词

结巴中文分词(https://github.com/fxsjy/jieba)是最流行的Python中文分词组件,它有一种搜索引擎模式,在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。下面是引用自它项目主页的示例:

可见它的分词数量比二元分词少了很多,对应地索引产寸也小了。使用二元分词时,4000万文档的表索引超过40GB,而使用结巴分词后,减少到约26GB。由上例也可看出,结巴分词的结果丢失了位置信息,所以查询词预处理过程也可以省略加入双引 ,这样MongoDB在全文搜索时计算量也大大少,搜索速度加速了数十倍。以牛仔裤为例,使用结巴分词后查询时间由10秒以上降到约400ms,而直接复制商品名进行长词查询,也基本上能够在5秒钟之内完成查询,可用性和用户体验都得到了巨大提升。

结巴分词的缺陷是需要行业词典进行分词。比如电商平台的商品名都有长度限制,都是针对搜索引擎优化过的,日常用语“”在电商平台上被优化成了“”,这显然不是一个通常意义上的词。在没有行业词典的情况下,结巴分词的结果是,用户搜索时,将计算“”和“”的结果交集;如果使用自定义词典,将优化为,则无需计算,搜索速度更快,但增加了维护自定义词典的成本。

组合全文索引(Compound text Index)

组合全文索引是MongoDB的一个特色功能,是指带有全文索引的组合索引。下面引用一个官方文档的例子:

通过这种方式,当查询部门()字段的描述中是否有某些词时,因为先过滤掉了大量的非同的文档,可以大大减少全文搜索的时间,从而实现性能优化。

尽管组合全文索引有许多限制,如查询时必须指定前缀字段,且前缀字段只支持等值条件匹配等,但实际应用中还是有很多适用场景的,比如商品集合中有分类字段,天然就是等值条件匹配的,在此情况根据前缀字段的分散程度,基本上可以获得同等比例的性能提升,一般都在10倍以上。

用户体验优化

MongoDB的全文搜索其实是很快的,但当需要根据其它字段进行排序的时候,就会显著变慢。比如在我们的场景中,当搜索并按销量排序时,速度显著变慢。所以在产品设计时,应将搜索功能独立,只解决“快速找出最想要的产品”这一个问题,想在一个功能里解决多个问题,必然需要付出性能代价。

另一个有助于提升提升用户体验的技术手段是一次搜索,大量缓存。就是一个搜索词第一次被查询时,直接返回前面若干条结果,缓存起来(比如放到Redis),当用户翻页或其他用户查询此词时,直接从缓存中读取即可,速度大幅提升。

实时性优化

前文提到编写索引程序对全文索引字段进行更新,但如果后面持续增加或修改数据时,也需要及时更新,否则实时性没有保障。在此可以引入Change Streams,它允许应用程序访问实时数据更改,而不必担心跟踪 oplog 的复杂性和风险。应用程序可以使用Change Streams来订阅单个集合、数据库或整个部署中的所有数据更改,并立即对它们作出反应。由于Change Streams使用聚合框架,应用程序还可以根据需要筛选特定的更改或转换通知。Change Streams也是MongoDB Atlas Search同步数据变化的方法,所以它是非常可靠的。使用Change Streams非常简单,我们的代码片断类似于这样:

在函数中我们检查可搜索字段是否产生了变化(更新或删除),如果是则对该文档更新_t字段,从而实时数据更新。

总结

============

赖勇浩,2005年至2012年在 易(广州)、广州银汉等公司从事 络游戏开发和技术管理工作。2013年至2014年在广东彩惠带领团队从事彩票行业数字化研发和实施。2015年至今,创办广州齐昌 络科技有限公司,后并入广东天勤科技有限公司,任职CTO,并且担任广州天勤数据有限公司联合创始人&CEO,现带领团队负责电商大数据分析软件的研发工作,形成由看店宝等十余个数据工具组成的产品矩阵,覆盖分析淘宝、天猫、拼多多和抖音等多个电商平台数据,服务全国各地200多万电商从业人员。热爱分享,于2009年联合创办程序员 区TechParty(原珠三角技术沙龙)并担任两届组委主席,于2021年创办中小团队技术管理者和技术专家 区小红花俱乐部,均深受目标群体的喜爱。

精通Python、C++、Java等编程语言和Linux操作系统,熟悉大规模多人在线系统的设计与实现,在大数据方面,对数据收集、清洗、存储、治理、分析等方面有丰富经验,设计和实现了准PB级别的基于MongoDB的电商数据湖系统,对冷热数据分级处理、系统成本控制和数据产品设计研发有一定心得。

曾在《计算机工程》等期刊发表多篇论文,于2014年出版《编写高质量代码:改善Python程序的91个建议》一书。

文章知识点与官方知识档案匹配,可进一步学习相关知识Python入门技能树首页概览211008 人正在系统学习中

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年6月1日
下一篇 2022年6月1日

相关推荐