1.前言
微信移动客户端全文搜索中的复调问题一直是搜索体验中的难点之一。微信客户端的全文搜索上线后,经常会收到用户对复音词的反馈。因此,微信全文搜索中复音词的搜索成为一个亟待解决的问题。本文主要研究基于SQLite FTS5的微信Android客户端复调问题的解决方案。
此外,微信团队在另一篇名为《优化微信手机本地数据全文检索的方法》的文章中分享了更详细的全文检索优化思路,这表明感兴趣的开发者可以深入了解。
建议:您也可以在微信客户端的sqlite数据库中找到本文相关技术的真实实现。微信本地数据库(包括iOS和安卓)的破解版可在此下载,仅供学习和研究[附件下载](特别:微信的SQLite样本数据库仅供研究和学习,严禁用于商业目的,所有权属于微信)。
2.相关文章
“优化微信手机本地数据全文检索之路”
腾讯技术共享:安卓手机QQ的缓存监控与优化实践
“微信团队共享:微信面向iOS的高性能通用关键价值组件技术实践”
“微信团队共享:iOS版本的微信如何防止由特殊人物引起的群体爆炸和应用崩溃?》
腾讯技术共享:安卓手q线程死锁监控系统的技术实践
“微信团队原创分享:iOS版微信内存监控系统技术实践”
“iOS后台唤醒战斗:微信收集和到达语音提醒技术总结”
“腾讯团队分享:分享在手q聊天界面图片中显示的bug追踪过程”
“微信团队透露:微信界面卡死了超级臭虫”15。。。。“的来龙去脉”
微信客户团队负责人技术访谈:如何启动客户绩效监控和优化
“微信团队原创分享:微信客户端SQLite数据库损坏修复练习”
“移动即时通讯实践:iOS微信界面点击监控方案”
"移动即时通讯实践:如何大幅提升微信对安卓的互动性能(上)"
"移动即时通讯实践:如何大幅提升微信对安卓的互动性能(二)"
“移动即时通讯实践:微信iOS版多设备字体适配方案探讨”
“原创鸽子队:在iOS10上穿越信息推送(APNS)的陷阱”
3.微信的全文检索要求
搜索表单:
拼音前缀搜索、中文和拼音不能混合搜索,输入的拼音必须是连续汉字的全拼音或短拼音。
搜索:
联系人、群组聊天和公共号码的评论和昵称(最大长度为16个中文字符)。
例如
联系人甲,昵称为“王宏伟”,需要通过以下方式搜索联系人甲的昵称:
微信团队分享:微信手机全文搜索复音词问题解决方案_1.jpeg
4.同义词库方案
如果中文全文搜索引擎需要支持拼音,它需要将输入的汉字转换成拼音字母。如果不考虑复音字符,我们只需要一个单个汉字的拼音表来实现转换。然而,在复音字符的情况下,每个汉字在不同的单词之间可能具有不同的发音,因此为了获得每个汉字的准确拼音,有必要引入拼音对应单词表。
众所周知,汉语博大精深。常用汉字有20777个,而单词(包括成语)中的汉字数量从2个到16个不等。同一个汉字在不同的单词中发音可能不同。
因此,有两种将中文单词转换成拼音的方案:
1)单词的详尽列表;
2)利用概率模型和训练分类器模型,得到汉字拼音。
第一种方案需要非常高的存储空间,并且消耗了太多的资源。
在第二种方案中,在现有的TTS(文本到语音)模型中,将汉字转换为拼音发音的模型进行了分解,并初步建立了概率模型。经过初步优化,得到了1 g拼音模型,拼音识别的准确率在可接受的范围内。由于模型的大小是GB,所以首先要考虑的是将模型放在后台进行处理。
处理流程如下:
微信团队分享:微信手机全文搜索复音词问题解决方案_2.png
优势:
客户端没有任何变化,所有版本的客户端都可以快速覆盖。
缺点:
用户修改注释或昵称后,需要等待后台发布拼音,才能得到正确的拼音索引,导致拼音索引建立不及时。微信用户数量巨大,用户修改短信和昵称的频率非常高,每天都有数十亿次修改,导致后台处理计算量大、耗时长,需要增加成本。
5.单词列表方案
常用汉字有20777个,总大小为200千字节,可以直接带给客户端,查询时间复杂度为0(1),从数据量来看是可以接受的。
优势:
用户修改昵称或备注后,可以快速响应并及时建立索引;
将后台的大量计算分散到用户的手机上,节省了成本;
对于姓名中汉字的发音,您可以搜索任何发音。
缺点:
就用户体验而言,单词中的复音词可以通过任意汉字的拼音进行搜索;
在综合考虑用户体验和性能问题后,微信最终选择了词表方案。
6.客户索引方案
在确定单词表方案后,应该在客户端本地使用SQLite FTS5来建立索引。由于拼音搜索主要采用前缀搜索,建立索引的内容和方法需要考虑FTS5前缀搜索的过程。
微信团队分享:微信手机全文搜索复音词问题解决方案_3.jpeg
路径(1)在创建索引表时使用前缀索引,因此当用户输入查询时,可以通过哈希方法搜索前缀索引表,直接找到所有以查询为前缀的结果。
路径(2)是构建索引表时不使用的前缀索引,因此当用户输入Query时,FTS5临时构建一个前缀树来查找将Query设置为Preifx的索引集。
路径1在时间复杂性方面有明显的优势,因此在创建索引时有必要添加前缀配置:
微信团队分享:微信手机全文搜索复音词问题解决方案_3.png
6.1指数方案一
考虑到用户输入是连续的,将不会考虑交叉拼音问题。
例如,当用户搜索“市委书记”的拼音时,他可以使用以下查询:
史
shiweishuj
盐水
根据上述用户输入习惯和FTS5前缀搜索原则,采用第一种索引方案:
微信团队分享:微信手机全文搜索复音词问题解决方案_5.png
当FTS5匹配上述查询时,用户1和2将被匹配为“十味书集”的前缀,而用户3将被匹配为“swsj”的前缀。
6.2指数方案二
索引方案一只考虑用户从拼音的开头开始搜索,而不考虑从中间开始搜索。
例如,以下查询:
姬叔
耶稣会
因此,当需要建立索引时,需要将每个汉字的拼音作为前缀建立在索引中,如下表所示:
微信团队分享:微信手机全文搜索复音词问题解决方案_6.png
6.3指数方案三
方案1和方案2是不考虑复音词的索引方案。引入复音词后,当组合拼音字符串时,每个拼音可能会有许多情况。
以下是用户备注“简章”的索引:
微信团队共享:微信手机全文搜索复音词问题解决方案_7.jpeg
昵称“张简”被索引后,得到如下索引结构:
微信团队共享:微信手机全文搜索复音词问题解决方案_8.jpeg
术语偏移量:表示某个文档中某个单词的偏移量;
DocID:文档的唯一ID。
一个单词可以通过一个文档标识和一个术语偏移量来定位。SQLite FTS5通过搜索一个单词来找到相应的文档标识,并通过术语偏移量来定位单词在文档中的位置。
方案的优点:
实现相对简单;
所有复音词都可以覆盖。
方案缺点:
索引数据量太大;
常用汉字有20777个,其中复音汉字2659个,占12.7%,每个复音汉字平均有2.14个拼音。
在微信场景中,联系人的备注和昵称的最大字符长度为16个字符,因此我们假设每个昵称的字符为16个汉字,每个汉字的拼音长度最长(7个英文字母+1个英文拼音字母)。
一般情况:
其中,20,777个汉字出现在昵称中的概率相同,因此16个汉字中大约会出现3个复音字符,公式如下:
微信团队分享:微信手机全文搜索复音词问题解决方案_9.png
极端情况:
昵称中的每个词都是一个复音词,每个复音词有四个读音,如“莫-莫-莫-莫-莫-莫-莫-莫”,公式如下:
微信团队分享:微信手机全文搜索复音词问题解决方案_10.jpeg
从以上两种情况可以看出,方案3在极端情况下会占用大量数据,因此方案3不可用。
6.4指数方案四
第三种方案用穷举的方法列举所有的拼音组合,其核心在于通过空间改变区域时间。当所需空间太大时,可以采用折衷方案。
在汉语中,具有相同含义的实体由两个不同的词来表示,这两个词被称为同义词,并被表示为(词a,词B)=(含义c)。在复音词的情况下,它也可以表示为(拼音a,拼音B)=(汉字c)。方案4的核心是通过同义词来表达各种拼音的组合。
在SQLite FTS5中,一个单词可以通过一个文档标识和一个术语偏移量来定位,因此当两个单词具有相同的文档标识和术语偏移量时,可以说这两个单词是同义词,并且可以使用以下索引方案:
微信团队共享:微信手机全文搜索复音词问题解决方案_11.jpeg
方案的优点:
少量索引数据:
1)一般条件:
微信团队分享:微信手机全文搜索复音词问题解决方案_12.png
2)极限情况:
微信团队分享:微信手机全文搜索复音词问题解决方案_13.png
索引速度很快。
方案缺点:
默认的单词分隔符不能适应复音单词的语音数据;
索引中的数据不能直接对应于用户输入。
为了解决第四种方案中的两个问题,我们引入了一个复音分词装置,并对用户输入进行了预处理。
7.复音分词器
SQLite FTS5的默认分隔符都是固定的,因此在识别拼音字符时,它们将被用作英文字母进行分词。为了实现所需的索引结构,我们引入了二级分隔符,并使用分号“;”分开不同的汉字和“,”分开同一汉字的不同拼音。
微信团队分享:微信手机全文搜索复音词问题解决方案_14.png
以下是复音分词器的分词过程:
微信团队共享:微信手机全文搜索复音词问题解决方案_15.jpeg
8.用户输入的预处理
当用户输入的是连续拼音时,因为索引中没有直接对应的术语,所以有必要将用户输入的查询分解成索引中可能的术语。
假设用户输入拼音:壮语,根据短拼音和全拼音的规则,可以得到以下7种搜索组合:
微信团队共享:微信手机全文搜索复音词问题解决方案_16.jpeg
考虑到最后一个拼音是一个前缀搜索,在列出拼音组合时,有必要考虑之前的完整拼音,而最后一个只能考虑它是否是某个拼音的前缀。
为了实现该算法,我们可以建立一个前缀树,将所有的拼音作为输入,这样可以将查询拼音反汇编的时间复杂度降低到0(nlgn)。
最后,将所有拼音组合写入SQL:
微信团队分享:微信手机全文搜索复音词问题解决方案_17.png
微信团队分享:微信手机全文搜索复音词问题解决方案_18.png
9.该计划的实际效果
与方案3和方案4相比,拼音数据明显提高了约50%。
微信团队共享:微信手机全文搜索复音词问题解决方案_19.jpeg
由于联系人拼音数据的减少,单个联系人的数据量减少,插入SQL的执行时间减少,建立联系人索引的时间也明显减少了30%左右。
微信团队分享:微信手机全文搜索复音词问题解决方案_20.jpeg
在搜索查询时,由于拼音组合的多样性,复音词方案增加了搜索哈希表的数量。然而,由于搜索哈希表的时间复杂度为0(1),并且在有限字符查询下拼音组合很少(少于20),搜索查询的时间增加了约15%。