Better Extended Live Archive:索引更新的困扰

前文提到,这些天我在往GitHub提交代码,就是在重写这个插件Better Extended Live Archive插件。今天就遇到一个难题。

插件原理

简单描述一下插件的原理,其实就是对WordPress所有的博文,建立一套倒排索引文件。(什么是倒排索引?,简单来说,就是依据文档的某个属性,检索文档,这个属性列表,就是倒排索引。举个例子,给出一个属性:2013年6月;那就要根据这个属性,找到所有符合的文档,那就会找到所有6月份的文章。而索引文件的存储,也是用属性作为主键的。再往通透了说,就是一个SQL查询语句的结果集合,缓存起来。)这套倒排索引,不是按照一般意义的,对文章进行分词,然后对所有属性建立倒排索引,而是仅对我们阅读和检索博客时候,最为关心的一些属性进行倒排索引,比如时间信息、分类信息、标记信息。

插件工作流程

初始化

初始化工作是非常简单的,其实就是根据时间、分类信息、标记信息对所有博客文章进行分类,然后将结果缓存起来,原作用的磁盘文件存储缓存结果,我在重构的时候,将缓存抽象成了接口,还是给出了磁盘文件的实现,当然,完全可以视需要,提供MySQL等DB存储,或者NoSQL存储,只要配置穿进去即可。

初始化归结下来,就两个:查询、存储结果。

更新

根据WordPress提供的事件触发机制,在博客的文章更新的时候,重新建立相关的索引。

展示

使用结构化的表现形势,将所有倒排索引展示在网页上,使用js添加动态内容更替特性,就显得非常的有意思。用起来流畅,而且方便。大家可以去这个页面体验下。

难题

现在来说说,到底困难的是什么?可以想见,这么一个倒排索引系统,其初始化工作的任务量是庞大的,因为相当于把所有博客文章拿出来,按照三种不同的纬度,进行三次分类操作。比如时间的最小粒度是月,我的博客持续6年,70个月左右,那其实基本上要查询70次,产生每个月的文章列表,分类是20个,那至少查询20次产生每个分类的文章列表,tag至少有100个,我只显示最常用的50个,那至少要50次查询来说生成每个tag的文章列表,于是乎,初始化一次,至少150次的查询,也就意味着,其实完整重建一遍所有的索引,查询在150次这个量级。

所以,在文章有所更新的时候,我们当然不希望所有的事情都重做一遍,那将会是一个漫长的等待,当然我的博客一共只有200多篇文章,再慢也像飞一样的,要考虑到插件的用户,好多老牌的博客,基本上500篇文章以上,我的插件的这种性能,他们可能来用么,不可能。我们要做增量更新,于是,每篇文章更新的时候,我们都要去探测,OK,哪个年份,哪个月份的索引需要重建?哪个分类,哪个tag的索引文件需要重建,然后我们重建这些变化部分,就是了。

然后难题出现了,怎么确定变化的部分?比如时间的分类纬度,是比较好处理的,插件选用的是发布时间,所以说,只要分析发布时间的年,月,日即可。但是分类和tag就麻烦了,按照现有的实现,只能在文章变更后,得知变更文章的id,那其实我很难判定,这篇文章到底影响了几个分类或者说几个tag,比如,你很难知道一个现在处于分类A中的文章,曾经,是不是处于过B和C分类,那影响分类可能是三个,也可能是一个。对于新发布的文章来说,我们可以强制认为是新增了一个分类,但是对于修改的文章呢?如果不追溯文章的版本,怎么可能知道文章先前的分类信息呢?

可能的解决方案

第一个,就是为所有文章保留正向索引,可以特意去建立一个,为了查询迅速。

第二个,设法在更新操作执行前,插入一个动作,保存住文章原有的分类信息,tag信息,在文章更新后,再插入一个动作,计算新的,然后做差就可以计算出变更了。

第三个,暂时没想到。