如题,做lucene搜索引擎时遇到的问题,不太会Web编程。只知道JSP支持从页面调后台,没用什么框架。
现在给出自己的一些设计思路,不一定高效,不一定主流。
我后台有个SearchService,其中有函数,大致是这样的:
public SearchResults search(String keyword);
现在要作结果分页,
要求1. 硬性要求: 同一次搜索,只调用一次search函数。即从第n页转到第m页时,不应该再去调用search(逻辑上应该搜一次就够了)
要求2. 非硬性要求: 页面之间尽量不要传递bean(不会,现学麻烦)要求1要满足,有两种方法
方法1.1. 页面之间传递SearchResults参数,这与要求2矛盾,先不考虑
方法1.2. 在后台搞一个能定制返回第几页的信息的函数,如getResults(int pageIndex),这实际上是在后台把也分好,前台直接调用
画了3小时左右,将方法1.2.实现出来了,发现速度太慢,因为后台是直接把所有数据全搜出来,然后放全内存里进行分页。
像google那样的引擎100%采取的是某种lazy-fetch策略。
改吧。
好了,画了5个小时,改了个lazy-fetch版的出来。在这需要说明,我页面的显示结果
并非直接来自索引。实际上,我是用索引取出对象(我的对象是开源项目,简称项目)名称,然后再用名称去查数据库,取出结果中要显示的其他字段。那么之前的耗时可能是有两方面:
1. 从索引中取出hit doc中项目名称的耗时,如果有>10^4的结果,这会很显著
2. 通过名称去查数据库的耗时,我用了hibernate,但数据量一大,耗时还是显著
经过简单分析,我认为2的耗时更大。因此考虑将其defer到各个页面(lazy-fetch,即进入每个页面在去针对该页做步骤2,这样一次取的数据量就在10~20 tuple这个量级了)。
这里为什么不把步骤1也defer呢?我有我的考虑。在我的应用中,索引搜索的hit doc与显示的结果项目并非一一对应,而是
好,现假设1可以defer,即
每页去取自己的Hit Document,从中找到项目名字段。因此
每页都应知道自己的Hit Document是哪些。
但是一页结果(比如对应20条条目)究竟能对应几个,哪几个Hit Document,必须在知道{a.各个项目名(包括其他页的)对应多少Hit Document}后才能确定。循环依赖,这事没法做。
最后就只defer了2,不知道我这种模式下能否defer 1,请高人支招。。。(我猜谷歌等要么就是defer了1的,要么就是他的索引和显示条目之间严格11对应,响应速度那么快)