Lucene5学习之分页查询

Java代码  

  1. package com.yida.framework.lucene5.core;  
  2.   
  3. import java.io.IOException;  
  4. import java.nio.file.Paths;  
  5. import java.util.ArrayList;  
  6. import java.util.List;  
  7.   
  8. import org.apache.lucene.analysis.standard.StandardAnalyzer;  
  9. import org.apache.lucene.document.Document;  
  10. import org.apache.lucene.index.DirectoryReader;  
  11. import org.apache.lucene.index.IndexReader;  
  12. import org.apache.lucene.queryparser.classic.ParseException;  
  13. import org.apache.lucene.queryparser.classic.QueryParser;  
  14. import org.apache.lucene.search.IndexSearcher;  
  15. import org.apache.lucene.search.Query;  
  16. import org.apache.lucene.search.ScoreDoc;  
  17. import org.apache.lucene.search.TopDocs;  
  18. import org.apache.lucene.store.FSDirectory;  
  19.   
  20. import com.yida.framework.lucene5.util.Page;  
  21.   
  22. /** 
  23.  * Lucene搜索第一个示例 
  24.  * @author Lanxiaowei 
  25.  * 
  26.  */  
  27. public class SearchFirstTest {  
  28.     public static void main(String[] args) throws ParseException, IOException {  
  29.         //参数定义  
  30.         String directoryPath = "D:/lucenedir";  
  31.         String fieldName = "contents";  
  32.         String queryString = "mount";  
  33.         int currentPage = 1;  
  34.         int pageSize = 10;  
  35.           
  36.         Page<Document> page = pageQuery(fieldName, queryString, directoryPath, currentPage, pageSize);  
  37.         if(page == null || page.getItems() == null || page.getItems().size() == 0) {  
  38.             System.out.println("No results found.");  
  39.             return;  
  40.         }  
  41.         for(Document doc : page.getItems()) {  
  42.             String path = doc.get("path");  
  43.             String content = doc.get("contents");  
  44.             System.out.println("path:" + path);  
  45.             System.out.println("contents:" + content);  
  46.         }  
  47.     }  
  48.     /** 
  49.      * 创建索引阅读器 
  50.      * @param directoryPath  索引目录 
  51.      * @return 
  52.      * @throws IOException   可能会抛出IO异常 
  53.      */  
  54.     public static IndexReader createIndexReader(String directoryPath) throws IOException {  
  55.         return DirectoryReader.open(FSDirectory.open(Paths.get(directoryPath, new String[0])));  
  56.     }  
  57.       
  58.     /** 
  59.      * 创建索引查询器 
  60.      * @param directoryPath   索引目录 
  61.      * @return 
  62.      * @throws IOException 
  63.      */  
  64.     public static IndexSearcher createIndexSearcher(String directoryPath) throws IOException {  
  65.         return new IndexSearcher(createIndexReader(directoryPath));  
  66.     }  
  67.       
  68.     /** 
  69.      * 创建索引查询器 
  70.      * @param reader 
  71.      * @return 
  72.      */  
  73.     public static IndexSearcher createIndexSearcher(IndexReader reader) {  
  74.         return new IndexSearcher(reader);  
  75.     }  
  76.       
  77.     /** 
  78.      * Lucene分页查询 
  79.      * @param directoryPath 
  80.      * @param query 
  81.      * @param page 
  82.      * @throws IOException 
  83.      */  
  84.     public static void pageQuery(String directoryPath,Query query,Page<Document> page) throws IOException {  
  85.         IndexSearcher searcher = createIndexSearcher(directoryPath);  
  86.         int totalRecord = searchTotalRecord(searcher,query);  
  87.         //设置总记录数  
  88.         page.setTotalRecord(totalRecord);  
  89.         TopDocs topDocs = searcher.searchAfter(page.getAfterDoc(),query, page.getPageSize());  
  90.         List<Document> docList = new ArrayList<Document>();  
  91.         ScoreDoc[] docs = topDocs.scoreDocs;  
  92.         int index = 0;  
  93.         for (ScoreDoc scoreDoc : docs) {  
  94.             int docID = scoreDoc.doc;  
  95.             Document document = searcher.doc(docID);  
  96.             if(index == docs.length - 1) {  
  97.                 page.setAfterDoc(scoreDoc);  
  98.                 page.setAfterDocId(docID);  
  99.             }  
  100.             docList.add(document);  
  101.             index++;  
  102.         }  
  103.         page.setItems(docList);  
  104.         searcher.getIndexReader().close();  
  105.     }  
  106.       
  107.     /** 
  108.      * 索引分页查询 
  109.      * @param fieldName 
  110.      * @param queryString 
  111.      * @param currentPage 
  112.      * @param pageSize 
  113.      * @throws ParseException  
  114.      * @throws IOException  
  115.      */  
  116.     public static Page<Document> pageQuery(String fieldName,String queryString,String directoryPath,int currentPage,int pageSize) throws ParseException, IOException {  
  117.         QueryParser parser = new QueryParser(fieldName, new StandardAnalyzer());  
  118.         Query query = parser.parse(queryString);  
  119.         Page<Document> page = new Page<Document>(currentPage,pageSize);  
  120.         pageQuery(directoryPath, query, page);  
  121.         return page;  
  122.     }  
  123.       
  124.     /** 
  125.      * @Title: searchTotalRecord 
  126.      * @Description: 获取符合条件的总记录数 
  127.      * @param query 
  128.      * @return 
  129.      * @throws IOException 
  130.      */  
  131.     public static int searchTotalRecord(IndexSearcher searcher,Query query) throws IOException {  
  132.         TopDocs topDocs = searcher.search(query, Integer.MAX_VALUE);  
  133.         if(topDocs == null || topDocs.scoreDocs == null || topDocs.scoreDocs.length == 0) {  
  134.             return 0;  
  135.         }  
  136.         ScoreDoc[] docs = topDocs.scoreDocs;  
  137.         return docs.length;  
  138.     }  
  139. }  

 其实查询的核心代码就这一句:
    

Java代码  

  1. searcher.searchAfter(page.getAfterDoc(),query, page.getPageSize());  

 searchAfter方法用于分页,如果不需要分页,请使用search方法。

searchAfter需要接收3个参数:

1.afterDocId即下一个Document的id,

2.query接口实现类的对象,query对象可以通过QueryParser类来创建,也可以自己new Query接口的某一个特定接口实现类,Query接口内置有N种实现,具体请查阅Lucene API,这里附上本人制作的Lucene5.0 API文档下载地址:http://pan.baidu.com/s/1uEgB8

3.pageSize即每页显示几条,你懂的。

 

至于如何创建IndexSearcher实例请看代码,跟Lucene4.x的使用方式没什么太大的区别,有一个较大的区别就是Lucene5.0里打开索引目录采用的是NIO2.0的方式,在Lucene4.0里你打开索引目录是这样的:

Java代码  

  1. FSDirectory.open(directoryPath);   

 这里的directoryPath为String类型即你的索引目录,而在Lucene5.0里,则是使用NIO2.0的方式:

Java代码  

  1. FSDirectory.open(Paths.get(directoryPath, new String[0]))  

 FSDirectory.open接收的参数不再是String类型而是Path类型。

 

 测试类里关联了一个自己写的Page分页工具类,代码如下:

Java代码  

  1. package com.yida.framework.lucene5.util;  
  2. import java.util.ArrayList;  
  3. import java.util.Collection;  
  4. import java.util.List;  
  5.   
  6. import org.apache.lucene.document.Document;  
  7. import org.apache.lucene.search.ScoreDoc;  
  8. public class Page<T> {  
  9.     /**当前第几页(从1开始计算)*/  
  10.     private int currentPage;  
  11.     /**每页显示几条*/  
  12.     private int pageSize;  
  13.     /**总记录数*/  
  14.     private int totalRecord;  
  15.     /**总页数*/  
  16.     private int totalPage;  
  17.     /**分页数据集合[用泛型T来限定集合元素类型]*/  
  18.     private Collection<T> items;  
  19.     /**当前显示起始索引(从零开始计算)*/  
  20.     private int startIndex;  
  21.     /**当前显示结束索引(从零开始计算)*/  
  22.     private int endIndex;  
  23.     /**一组最多显示几个页码[比如Google一组最多显示10个页码]*/  
  24.     private int groupSize;  
  25.       
  26.     /**左边偏移量*/  
  27.     private int leftOffset = 5;  
  28.     /**右边偏移量*/  
  29.     private int rightOffset = 4;  
  30.     /**当前页码范围*/  
  31.     private String[] pageRange;  
  32.       
  33.     /**分页数据*/  
  34.     private List<Document> docList;  
  35.     /**上一页最后一个ScoreDoc对象*/  
  36.     private ScoreDoc afterDoc;  
  37.       
  38.     /**上一页最后一个ScoreDoc对象的Document对象ID*/  
  39.     private int afterDocId;  
  40.   
  41.     public void setRangeIndex() {  
  42.         int groupSize = getGroupSize();  
  43.         int totalPage = getTotalPage();  
  44.         if(totalPage < 2) {  
  45.             startIndex = 0;  
  46.             endIndex = totalPage - startIndex;  
  47.         } else {  
  48.             int currentPage = getCurrentPage();  
  49.             if(groupSize >= totalPage) {  
  50.                 startIndex = 0;  
  51.                 endIndex = totalPage - startIndex - 1;  
  52.             } else {  
  53.                 int leftOffset = getLeftOffset();  
  54.                 int middleOffset = getMiddleOffset();  
  55.                 if(-1 == middleOffset) {  
  56.                     startIndex = 0;  
  57.                     endIndex = groupSize - 1;  
  58.                 } else if(currentPage <= leftOffset) {  
  59.                     startIndex = 0;  
  60.                     endIndex = groupSize - 1;  
  61.                 } else {  
  62.                     startIndex = currentPage - leftOffset - 1;  
  63.                     if(currentPage + rightOffset > totalPage) {  
  64.                         endIndex = totalPage - 1;  
  65.                     } else {  
  66.                         endIndex = currentPage + rightOffset - 1;  
  67.                     }  
  68.                 }  
  69.             }  
  70.         }  
  71.     }  
  72.       
  73.     public int getCurrentPage() {  
  74.         if(currentPage <= 0) {  
  75.             currentPage = 1;  
  76.         } else {  
  77.             int totalPage = getTotalPage();  
  78.             if(totalPage > 0 && currentPage > getTotalPage()) {  
  79.                 currentPage = totalPage;  
  80.             }  
  81.         }  
  82.         return currentPage;  
  83.     }  
  84.     public void setCurrentPage(int currentPage) {  
  85.         this.currentPage = currentPage;  
  86.     }  
  87.     public int getPageSize() {  
  88.         if(pageSize <= 0) {  
  89.             pageSize = 10;  
  90.         }  
  91.         return pageSize;  
  92.     }  
  93.     public void setPageSize(int pageSize) {  
  94.         this.pageSize = pageSize;  
  95.     }  
  96.     public int getTotalRecord() {  
  97.         return totalRecord;  
  98.     }  
  99.     public void setTotalRecord(int totalRecord) {  
  100.         this.totalRecord = totalRecord;  
  101.     }  
  102.     public int getTotalPage() {  
  103.         int totalRecord = getTotalRecord();  
  104.         if(totalRecord == 0) {  
  105.             totalPage = 0;  
  106.         } else {  
  107.             int pageSize = getPageSize();  
  108.             totalPage = totalRecord % pageSize == 0 ? totalRecord / pageSize : (totalRecord / pageSize) + 1;  
  109.         }  
  110.         return totalPage;  
  111.     }  
  112.     public void setTotalPage(int totalPage) {  
  113.         this.totalPage = totalPage;  
  114.     }  
  115.       
  116.     public int getStartIndex() {  
  117.         return startIndex;  
  118.     }  
  119.     public void setStartIndex(int startIndex) {  
  120.         this.startIndex = startIndex;  
  121.     }  
  122.       
  123.     public int getEndIndex() {  
  124.         return endIndex;  
  125.     }  
  126.     public void setEndIndex(int endIndex) {  
  127.         this.endIndex = endIndex;  
  128.     }  
  129.     public int getGroupSize() {  
  130.         if(groupSize <= 0) {  
  131.             groupSize = 10;  
  132.         }  
  133.         return groupSize;  
  134.     }  
  135.     public void setGroupSize(int groupSize) {  
  136.         this.groupSize = groupSize;  
  137.     }  
  138.       
  139.     public int getLeftOffset() {  
  140.         leftOffset = getGroupSize() / 2;  
  141.         return leftOffset;  
  142.           
  143.     }  
  144.     public void setLeftOffset(int leftOffset) {  
  145.         this.leftOffset = leftOffset;  
  146.     }  
  147.     public int getRightOffset() {  
  148.         int groupSize = getGroupSize();  
  149.         if(groupSize % 2 == 0) {  
  150.             rightOffset = (groupSize / 2) - 1;  
  151.         } else {  
  152.             rightOffset = groupSize / 2;  
  153.         }  
  154.         return rightOffset;  
  155.     }  
  156.     public void setRightOffset(int rightOffset) {  
  157.         this.rightOffset = rightOffset;  
  158.     }  
  159.       
  160.     /**中心位置索引[从1开始计算]*/  
  161.     public int getMiddleOffset() {  
  162.         int groupSize = getGroupSize();  
  163.         int totalPage = getTotalPage();  
  164.         if(groupSize >= totalPage) {  
  165.             return -1;  
  166.         }  
  167.         return getLeftOffset() + 1;  
  168.     }  
  169.     public String[] getPageRange() {  
  170.         setRangeIndex();  
  171.         int size = endIndex - startIndex + 1;  
  172.         if(size <= 0) {  
  173.             return new String[0];  
  174.         }  
  175.         if(totalPage == 1) {  
  176.             return new String[] {"1"};  
  177.         }  
  178.         pageRange = new String[size];  
  179.         for(int i=0; i < size; i++) {  
  180.             pageRange[i] = (startIndex + i + 1) + "";  
  181.         }  
  182.         return pageRange;  
  183.     }  
  184.   
  185.     public void setPageRange(String[] pageRange) {  
  186.         this.pageRange = pageRange;  
  187.     }  
  188.   
  189.     public Collection<T> getItems() {  
  190.         return items;  
  191.     }  
  192.     public void setItems(Collection<T> items) {  
  193.         this.items = items;  
  194.     }  
  195.       
  196.     public List<Document> getDocList() {  
  197.         return docList;  
  198.     }  
  199.   
  200.     public void setDocList(List<Document> docList) {  
  201.         this.docList = docList;  
  202.     }  
  203.   
  204.     public ScoreDoc getAfterDoc() {  
  205.         setAfterDocId(afterDocId);  
  206.         return afterDoc;  
  207.     }  
  208.   
  209.     public void setAfterDoc(ScoreDoc afterDoc) {  
  210.         this.afterDoc = afterDoc;  
  211.     }  
  212.       
  213.     public int getAfterDocId() {  
  214.         return afterDocId;  
  215.     }  
  216.   
  217.     public void setAfterDocId(int afterDocId) {  
  218.         this.afterDocId = afterDocId;  
  219.         if(null == afterDoc) {  
  220.             this.afterDoc = new ScoreDoc(afterDocId, 1.0f);  
  221.         }  
  222.     }  
  223.       
  224.     public Page() {}  
  225.   
  226.     public Page(int currentPage, int pageSize) {  
  227.         this.currentPage = currentPage;  
  228.         this.pageSize = pageSize;  
  229.     }  
  230.   
  231.     public Page(int currentPage, int pageSize, Collection<T> items) {  
  232.         this.currentPage = currentPage;  
  233.         this.pageSize = pageSize;  
  234.         this.items = items;  
  235.     }  
  236.   
  237.     public Page(int currentPage, int pageSize, Collection<T> items, int groupSize) {  
  238.         this.currentPage = currentPage;  
  239.         this.pageSize = pageSize;  
  240.         this.items = items;  
  241.         this.groupSize = groupSize;  
  242.     }  
  243.   
  244.     public Page(int currentPage, int pageSize, int groupSize, int afterDocId) {  
  245.         this.currentPage = currentPage;  
  246.         this.pageSize = pageSize;  
  247.         this.groupSize = groupSize;  
  248.         this.afterDocId = afterDocId;  
  249.     }  
  250.   
  251.     public static void main(String[] args) {  
  252.         Collection<Integer> items = new ArrayList<Integer>();  
  253.         int totalRecord = 201;  
  254.         for(int i=0; i < totalRecord; i++) {  
  255.             items.add(new Integer(i));  
  256.         }  
  257.         Page<Integer> page = new Page<Integer>(1,10,items,10);  
  258.         page.setTotalRecord(totalRecord);  
  259.         int totalPage = page.getTotalPage();  
  260.         for(int i=0; i < totalPage; i++) {  
  261.             page.setCurrentPage(i+1);  
  262.             String[] pageRange = page.getPageRange();  
  263.             System.out.println("当前第" + page.currentPage + "页");  
  264.             for(int j=0; j < pageRange.length; j++) {  
  265.                 System.out.print(pageRange[j] + "  ");  
  266.             }  
  267.             System.out.println("\n");  
  268.         }     
  269.     }  
  270. }  

 

来张运行效果图大家感受下:

 

 demo源代码请在附件里下载,千言万语都在代码中,你们懂的。

若你还有什么疑问,请加我Q-Q:7-3-6-0-3-1-3-0-5,或者加裙:

,欢迎你加入一起交流学习。

转载:http://iamyida.iteye.com/blog/2193345

时间: 2024-10-03 16:21:40

Lucene5学习之分页查询的相关文章

Lucene5学习之多线程创建索引

    昨晚睡觉前把多线程创建索引demo写好了,今天早上7点多就起来,趁着劲头赶紧记录分享一下,这样对那些同样对Lucene感兴趣的童鞋也有所帮助.     我们都知道Lucene的IndexWriter在构造初始化的时候会去获取索引目录的写锁writerLock,加锁的目的就是保证同时只能有一个IndexWriter实例在往索引目录中写数据,具体看截图:  而在多线程环境下,光保证只有IndexWriter实例能得到锁还不行,还必须保证每次只能有一个线程能获取到writerLock,Luce

Lucene5学习之LuceneUtils工具类简单封装

     周六花了整整一下午,将Lucene5中有关索引的常见操作进行了简单封装,废话不多说,上代码:   Java代码   package com.yida.framework.lucene5.util;      import java.io.IOException;   import java.util.concurrent.ExecutorService;   import java.util.concurrent.locks.Lock;   import java.util.concu

Java操作MongoDB模糊查询和分页查询_java

本文实例为大家分享了Java操作MongoDB模糊查询和分页查询,供大家参考,具体内容如下 模糊查询条件: 1.完全匹配 Pattern pattern = Pattern.compile("^name$", Pattern.CASE_INSENSITIVE); 2.右匹配 Pattern pattern = Pattern.compile("^.*name$", Pattern.CASE_INSENSITIVE); 3.左匹配 Pattern pattern =

.NET平台开源项目速览(7)关于NoSQL数据库LiteDB的分页查询解决过程

原文:.NET平台开源项目速览(7)关于NoSQL数据库LiteDB的分页查询解决过程 在文章:这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧!(第二辑) 与 .NET平台开源项目速览(3)小巧轻量级NoSQL文件数据库LiteDB中,介绍了LiteDB的基本使用情况以及部分技术细节,我还没有在实际系统中大量使用,但文章发布后,有不少网友( loogn)反应在实际项目中使用过,效果还可以吧.同时也有人碰到了关于LiteDB关于分页的问题,还不止一个网友,很显然这个问题从我的思考上来

Lucene5学习之Filter过滤器

  清明3天假,我猜小伙伴们都相约出去玩去了,对于我等屌丝来说,唯有在家写代码打发时间了.其实不是我喜欢宅,只是一个人去哪儿都没有激情,还不如在家安安静静的看看书写写代码来的安逸,对这个看脸的世界就差绝望了,就算代码虐我千万遍,我待代码还是如初恋啊!今天从早上9点起来,就中午做个饭,一坐就是整整10个小时,照着我预想的计划继续记录我的Lucene5学习轨迹,由于Filter体系下子类有点多,还要编写测试demo,所以这篇博客有点姗姗来迟,请大家多多包涵!                    

数据库分页查询方法_数据库其它

可能会有人说这些网上都有,但我的主要目的是把这些知识通过我实际的应用总结归纳一下,以方便大家查询使用. 下面就分别给大家介绍.讲解一下三种数据库实现分页查询的方法. 一. MySQL 数据库分页查询 MySQL数据库实现分页比较简单,提供了LIMIT函数.一般只需要直接写到sql语句后面就行了. LIMIT子句可以用来限制由SELECT语句返回过来的数据数量,它有一个或两个参数,如果给出两个参数, 第一个参数指定返回的第一行在所有数据中的位置,从0开始(注意不是1),第二个参数指定最多返回行数.

新闻列表的分页查询java代码实现_java

本文实例为大家分享了新闻列表分页查询的java代码,供大家参考,具体内容如下 package com.ibeifeng.test; //创建新闻测试类 public class newTest { private long id; private String title; private String content; private String author; public newTest() { super(); } public newTest(long id, String titl

完美实现bootstrap分页查询_javascript技巧

最近,开始我们的Java项目,要求尽量使用bootstrap,因为它比easyUI要好看的多.然后就开始上网查,边查边做,虽然我们引入了一些bootstrap的样式,但是并没有js代码,所有的功能都需要自己用js做.其实并不难,只要我们明白分页的实质就行.说了这么多,就让我们看看分页查询的表格是怎么做出来的吧. 先上效果图: 1.引入的css样式我们需要引入bootstrap自带的表格样式,这样比较好看,如果再需要修改的话,我们就在其基础上再改. <link rel="stylesheet

ibatis分页查询

问题描述 求助,ibatis分页查询的完整代码 解决方案 解决方案二:你需要重写下com.ibatis.sqlmap.engine.execution.SqlExecutor中的executeQuery()函数,要写的东西有很多,建议好好搜索学习下解决方案三:........................解决方案四:这个很简单你查一下就可以了解决方案五:下个例子抄写把.看来lzjsp没做过几个项目.解决方案六:引用3楼wzdsll5211314的回复: 这个很简单你查一下就可以了 你问问题的时