基于lucene两个分页:
lucene3.5查询方式(每次查询所有记录,然后取当中部分记录。这样的方式用的最多),lucene官方的解释:因为我们的速度足够快。
处理海量数据时。内存easy内存溢出。
lucene3.5以后提供一个searchAfter,这个是在特大数据量採用(亿级数据量),速度相对慢一点,像google搜索图片的时候,点击很多其它,然后再出来一批。这样的方式就是把数据保存在缓存里面。然后再去取。
下面是再查询部分代码:
/** * 这就是先查询全部的数据。然后去分页数据 * 注意 这样的方式处理海量数据的时候,easy内存溢出 * @param query * @param pageIndex--第几页 * @param pageSize--每页显示多少数据 */ public void searchPage(String query,int pageIndex,int pageSize) { try { Directory dir = FileIndexUtils.getDirectory(); IndexSearcher searcher = getSearcher(dir); QueryParser parser = new QueryParser(Version.LUCENE_35,"content",new StandardAnalyzer(Version.LUCENE_35)); Query q = parser.parse(query); TopDocs tds = searcher.search(q, 500); //注意 此处把500条数据放在内存里。 ScoreDoc[] sds = tds.scoreDocs; int start = (pageIndex-1)*pageSize; int end = pageIndex*pageSize; for(int i=start;i<end;i++) { Document doc = searcher.doc(sds[i].doc); System.out.println(sds[i].doc+":"+doc.get("path")+"-->"+doc.get("filename")); } searcher.close(); } catch (org.apache.lucene.queryParser.ParseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
最后我们来看下使用SearcherAfter进行分页的方式,代码例如以下(lucene3.5之前 不支持该方法):
/** * 依据页码和分页大小获取上一次的最后一个scoredocs * @param pageIndex * @param pageSize * @param query * @param searcher * @return * @throws IOException */ private ScoreDoc getLastScoreDoc(int pageIndex,int pageSize,Query query,IndexSearcher searcher) throws IOException { if(pageIndex==1)return null;//假设是第一页就返回空 int num = pageSize*(pageIndex-1);//获取上一页的最后数量 TopDocs tds = searcher.search(query, num); return tds.scoreDocs[num-1]; } public void searchPageByAfter(String query,int pageIndex,int pageSize) { try { Directory dir = FileIndexUtils.getDirectory(); IndexSearcher searcher = getSearcher(dir); QueryParser parser = new QueryParser(Version.LUCENE_35,"content",new StandardAnalyzer(Version.LUCENE_35)); Query q = parser.parse(query); //获取上一页的最后一个元素 ScoreDoc lastSd = getLastScoreDoc(pageIndex, pageSize, q, searcher); //通过最后一个元素去搜索下一页的元素 TopDocs tds = searcher.searchAfter(lastSd,q, pageSize); for(ScoreDoc sd:tds.scoreDocs) { Document doc = searcher.doc(sd.doc); System.out.println(sd.doc+":"+doc.get("path")+"-->"+doc.get("filename")); } searcher.close(); } catch (org.apache.lucene.queryParser.ParseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }