看完前两篇博客之后,想必大家对于Lucene的使用都有了一个比较清晰的认识了。如果对Lucene的知识点还是有点模糊的话,个人建议还是先看看这两篇文章。

全文检索 Lucene(1)

全文检索 Lucene(2)

下面来谈一谈使用Lucene查询的分页机制

分页原理

分页就是为了给用户展现一个逻辑性更强,页面更加紧凑的视图效果。相比于数据库实现的分页,Lucene就显得有点逊色了。毕竟数据库是原生支持的,这点没法改变。

这里说的对Lucene实现的分页机制其实并不是真正的分页,不妨这样想,当我们的TopDocs的大小设置很大,我们的电脑势必会出现内存不足的情况,即使有虚拟内存技术,这也是没办法消除的。这样的话查询机制就会崩溃。这一点我们待会再讲。

Dao层代码实现

由于本例是基于全文检索 Lucene(2)的延伸,所以就不再重新贴出那么多的代码了。这里仅仅是核心逻辑。

页面对象

  1. /**
  2. * @Date 2016年8月1日
  3. *
  4. * @author Administrator
  5. */
  6. package domain;
  7. import java.util.List;
  8. /**
  9. * @author 郭瑞彪
  10. *
  11. */
  12. public class Page<T> {
  13. private List<T> lists;
  14. private int totalResults;
  15. public List<T> getLists() {
  16. return lists;
  17. }
  18. public void setLists(List<T> lists) {
  19. this.lists = lists;
  20. }
  21. public int getTotalResults() {
  22. return totalResults;
  23. }
  24. public void setTotalResults(int totalResults) {
  25. this.totalResults = totalResults;
  26. }
  27. @Override
  28. public String toString() {
  29. return "Page [lists=" + lists + ", totalResults=" + totalResults + "]";
  30. }
  31. }

分页方法

  1. /**
  2. * 从索引库中查询
  3. *
  4. * <br>
  5. * 支持分页技术
  6. *
  7. * @param queryString
  8. * 查询字符串
  9. * @return
  10. */
  11. public Page search(String queryString, int firstResult, int maxResult) {
  12. try {
  13. // 1.queryString -->>Query
  14. String[] queryFields = new String[] { "title", "content" };
  15. Analyzer analyzer = new StandardAnalyzer();
  16. analyzer.setVersion(Version.LUCENE_6_0_0.LUCENE_6_1_0);
  17. QueryParser queryParser = new MultiFieldQueryParser(queryFields, analyzer);
  18. Query query = queryParser.parse(queryString);
  19. // 2. 查询,得到topDocs
  20. IndexSearcher indexSearcher = LuceneUtils.getIndexSearcher();
  21. TopDocs topDocs = indexSearcher.search(query, 100);
  22. // 3.处理结果并返回
  23. int totalHits = topDocs.totalHits;
  24. ScoreDoc[] scoreDocs = topDocs.scoreDocs;
  25. List<Article> articles = new ArrayList<Article>();
  26. int upperBound = (firstResult + maxResult) < scoreDocs.length ? (firstResult + maxResult)
  27. : scoreDocs.length;
  28. firstResult = (firstResult >= 0 ? firstResult : 0);
  29. for (int i = firstResult; i < upperBound; i++) {
  30. ScoreDoc scoreDoc = scoreDocs[i];
  31. Document doc = indexSearcher.doc(scoreDoc.doc);
  32. Article a = ArticleDocumentUtils.document2Article(doc);
  33. articles.add(a);
  34. }
  35. LuceneUtils.closeIndexSearcher(indexSearcher);
  36. // 处理查询结果,返回一个封装好的页面对象
  37. Page<Article> page = new Page();
  38. page.setLists(articles);
  39. page.setTotalResults(totalHits);
  40. return page != null ? page : null;
  41. } catch (Exception e) {
  42. throw new RuntimeException("ArticleIndexDao-->> search方法出错!\n" + e);
  43. }
  44. }

核心释义

我对分页的理解:

以Java面向对象的思维,页面本身就是一个对象。我们不妨现在就打开一个搜索引擎,搜索一下。看看页面结果。大概就能知道底层有什么东西了。

一般来说,做分页一定要知道总的记录数,然后是从哪一页开始分页。这是很有必要的。而且边界值我们也需要好好的进行维护。

  1. int upperBound = (firstResult + maxResult) < scoreDocs.length ? (firstResult + maxResult)
  2. : scoreDocs.length;
  3. firstResult = (firstResult >= 0 ? firstResult : 0);

Lucene伪分页:

下面接着上面没说完的关于Lucene的伪分页。我们也可以从代码中看出

  1. // 2. 查询,得到topDocs
  2. IndexSearcher indexSearcher = LuceneUtils.getIndexSearcher();
  3. TopDocs topDocs = indexSearcher.search(query, 100);
  4. // 3.处理结果并返回
  5. int totalHits = topDocs.totalHits;
  6. ScoreDoc[] scoreDocs = topDocs.scoreDocs;
  7. for (int i = firstResult; i < upperBound; i++) {
  8. ScoreDoc scoreDoc = scoreDocs[i];
  9. Document doc = indexSearcher.doc(scoreDoc.doc);
  10. Article a = ArticleDocumentUtils.document2Article(doc);
  11. articles.add(a);
  12. }

我们可以看出indexSearcher.search(query, 100);。我们还是查询到了小于等于前100得分项的记录,想象一个这个100设置成10000000000000000呢?结果会怎么样? 估计电脑会受不了的吧。

所以从这里也可以看出,不是任何情况都是适合适用Lucene的,搜们要根据需求来决定。

全文检索 Lucene(3)的更多相关文章

  1. 全文检索 Lucene(4)

    经过了前面几篇文章的学习,我们基本上可以适用Lucene来开发我们的站内搜索应用了.但是观察一下目前的主流的搜索引擎,我们会发现查询结果会有高亮的显示效果.所以,今天我们就来学习一下,给Lucene添 ...

  2. 全文检索Lucene (2)

    接着全文检索Lucene (1) . 下面我们来深入的研究一下,如何使用Lucene! 从全文检索Lucene (1)中我们可以看出,Lucene就好比一个双向的工作流,一方面是对索引库的维护,另一方 ...

  3. Lucene 全文检索 Lucene的使用

    Lucene  全文检索  Lucene的使用 一.简介: 参考百度百科: http://baike.baidu.com/link?url=eBcEVuUL3TbUivRvtgRnMr1s44nTE7 ...

  4. 全文检索--Lucene & ElasticSearch

    全文检索--Lucene 2.1 全文检索和以前高级查询的比较 1.高级查询 缺点:1.like让数据库索引失效 2.每次查询都是查询数据库 ,如果访问的人比较多,压力也是比较大 2.全文检索框架:A ...

  5. [全文检索]Lucene基础入门.

    本打算直接来学习Solr, 现在先把Lucene的只是捋一遍. 本文内容: 1. 搜索引擎的发展史 2. Lucene入门 3. Lucene的API详解 4. 索引调优 5. Lucene搜索结果排 ...

  6. 全文检索Lucene (1)

    Lucene是apache开源的一个全文检索框架,很是出名.今天先来分享一个类似于HelloWorld级别的使用. 工作流程 依赖 我们要想使用Lucene,那就得先引用人家的jar包了.下面列举一下 ...

  7. 全文检索-Lucene.net

    Lucene.net是Lucene的.net移植版本,在较早之前是比较受欢迎的一个开源的全文检索引擎开发包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎. ...

  8. 全文检索Lucene框架---查询索引

    一. Lucene索引库查询 对要搜索的信息创建Query查询对象,Lucene会根据Query查询对象生成最终的查询语法,类似关系数据库Sql语法一样Lucene也有自己的查询语法,比如:“name ...

  9. ]NET Core Lucene.net和PanGu分词实现全文检索

    Lucene.net和PanGu分词实现全文检索 Lucene.net(4.8.0) 学习问题记录五: JIEba分词和Lucene的结合,以及对分词器的思考   前言:目前自己在做使用Lucene. ...

随机推荐

  1. hdu 5392

    Sample Input 2 3 1 3 2 6 2 3 4 5 6 1   Sample Output 2 6 题意:给一个转置求它的循环长度 题解:分解成循环求最小公倍数 #include< ...

  2. 2015 多校联赛 ——HDU5302(构造)

    Connect the Graph Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  3. hdu 3247 AC自动+状压dp+bfs处理

    Resource Archiver Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Ot ...

  4. SPOJ NSUBSTR

    You are given a string S which consists of 250000 lowercase latin letters at most. We define F(x) as ...

  5. bzoj2127

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 2492  Solved: 1205[Submit][Status][D ...

  6. linux内核input子系统解析【转】

    转自:http://emb.hqyj.com/Column/Column289.htm 时间:2017-01-04作者:华清远见 Android.X windows.qt等众多应用对于linux系统中 ...

  7. Delphi 日期时间函数

    DateUtils.IncYear();DateUtils.IncMonth();DateUtils.IncWeek();DateUtils.IncDay();DateUtils.IncHour(); ...

  8. spring AOP的两种配置方式

    连接点(JoinPoint) ,就是spring允许你是通知(Advice)的地方,那可就真多了,基本每个方法的前.后(两者都有也行),或抛出异常是时都可以是连接点,spring只支持方法连接点.其他 ...

  9. js去掉最后一个字符

    console.log(("0,1,2,3,4,5,".slice(0,-1)))

  10. html下载excel模板

    只需要href等于模板存放的路径即可 <a href="../../TempLate/Attitude.xlsx" class="easyui-linkbutton ...