package com.think3c.lucene.index; import java.io.IOException; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexReader; import org.apache.lucene.queryparser.classic.ParseException; import org.apache.lucene.queryparser.classic.QueryParser; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TopDocs; import org.apache.lucene.store.FSDirectory; public class IndexSearch { /** * 创建索引阅读器 * * @param directoryPath * 索引目录 * @return 索引阅读器 * @throws IOException * 可能会抛出IO异常 */ public static IndexReader createIndexReader(String directoryPath) throws IOException { /** * 跟Lucene4.x的使用方式有一个较大的区别就是Lucene5.0里打开索引目录采用的是NIO2.0的方式,在Lucene4.0里你打开索引目录是这样的: * FSDirectory.open(directoryPath); * * 这里的directoryPath为String类型即你的索引目录,而在Lucene5.0里,则是使用NIO2.0的方式: * FSDirectory.open(Paths.get(directoryPath, new String[0])) * FSDirectory.open接收的参数不再是String类型而是Path类型。 */ return DirectoryReader.open(FSDirectory.open(Paths.get(directoryPath))); } /** * 创建索引查询器 * * @param reader * @return */ public static IndexSearcher createIndexSearcher(IndexReader reader) { return new IndexSearcher(reader); } /** * 通过索引目录找到对应的索引查询器 * * @param directoryPath * 目录文件 * @return */ public static IndexSearcher createIndexSearcher(String directoryPath) throws IOException { return new IndexSearcher(createIndexReader(directoryPath)); } /** * Lucene分页查询 * * @param directoryPath * @param query * @param page * @throws IOException */ public static void pageQuery(String directoryPath, Query query, Page<Document> page) throws IOException { IndexSearcher searcher = createIndexSearcher(directoryPath); int totalRecord = searchTotalRecord(searcher, query); // 设置总的条数 page.setTotalRecord(totalRecord); // searchAfter方法用于分页,如果不需要分页,请使用search方法。search(Query query, int n) /** * 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即每页显示几条,你懂的。 */ TopDocs topDocs = searcher.searchAfter(page.getAfterDoc(), query, page.getPageSize()); List<Document> docList = new ArrayList<Document>(); ScoreDoc[] docs = topDocs.scoreDocs; int index = 0; for (ScoreDoc scoreDoc : docs) { int docID = scoreDoc.doc; Document document = searcher.doc(docID); if(index == docs.length - 1) { page.setAfterDoc(scoreDoc); page.setAfterDocId(docID); } docList.add(document); index++; } page.setItems(docList); searcher.getIndexReader().close(); } /** * 索引分页查询 * @param fieldName * @param queryString * @param directoryPath * @param currentPage * @param pageSize * @return * @throws ParseException * @throws IOException */ public static Page<Document> pageQuery(String fieldName,String queryString,String directoryPath,int currentPage,int pageSize) throws ParseException, IOException{ QueryParser parser = new QueryParser(fieldName, new StandardAnalyzer()); Query query = parser.parse(queryString); Page<Document> page = new Page<Document>(currentPage,pageSize); pageQuery(directoryPath, query, page); return page; } /** * 获得符合条件的总数 * * @param searcher * @param query * @return * @throws IOException */ private static int searchTotalRecord(IndexSearcher searcher, Query query) throws IOException { TopDocs topDocs = searcher.search(query, Integer.MAX_VALUE); if (topDocs == null || topDocs.scoreDocs == null || topDocs.scoreDocs.length == 0) { return 0; } ScoreDoc[] docs = topDocs.scoreDocs; return docs.length; } }
添加自己对应的page对象。
package com.think3c.lucene.index; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.apache.lucene.document.Document; import org.apache.lucene.search.ScoreDoc; public class Page<T> { /** 当前第几页(从1开始计算) */ private int currentPage; /** 每页显示几条 */ private int pageSize; /** 总记录数 */ private int totalRecord; /** 总页数 */ private int totalPage; /** 分页数据集合[用泛型T来限定集合元素类型] */ private Collection<T> items; /** 当前显示起始索引(从零开始计算) */ private int startIndex; /** 当前显示结束索引(从零开始计算) */ private int endIndex; /** 一组最多显示几个页码[比如Google一组最多显示10个页码] */ private int groupSize; /** 左边偏移量 */ private int leftOffset = 5; /** 右边偏移量 */ private int rightOffset = 4; /** 当前页码范围 */ private String[] pageRange; /** 分页数据 */ private List<Document> docList; /** 上一页最后一个ScoreDoc对象 */ private ScoreDoc afterDoc; /** 上一页最后一个ScoreDoc对象的Document对象ID */ private int afterDocId; public void setRangeIndex() { int groupSize = getGroupSize(); int totalPage = getTotalPage(); if (totalPage < 2) { startIndex = 0; endIndex = totalPage - startIndex; } else { int currentPage = getCurrentPage(); if (groupSize >= totalPage) { startIndex = 0; endIndex = totalPage - startIndex - 1; } else { int leftOffset = getLeftOffset(); int middleOffset = getMiddleOffset(); if (-1 == middleOffset) { startIndex = 0; endIndex = groupSize - 1; } else if (currentPage <= leftOffset) { startIndex = 0; endIndex = groupSize - 1; } else { startIndex = currentPage - leftOffset - 1; if (currentPage + rightOffset > totalPage) { endIndex = totalPage - 1; } else { endIndex = currentPage + rightOffset - 1; } } } } } public int getCurrentPage() { if (currentPage <= 0) { currentPage = 1; } else { int totalPage = getTotalPage(); if (totalPage > 0 && currentPage > getTotalPage()) { currentPage = totalPage; } } return currentPage; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } public int getPageSize() { if (pageSize <= 0) { pageSize = 10; } return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public int getTotalRecord() { return totalRecord; } public void setTotalRecord(int totalRecord) { this.totalRecord = totalRecord; } public int getTotalPage() { int totalRecord = getTotalRecord(); if (totalRecord == 0) { totalPage = 0; } else { int pageSize = getPageSize(); totalPage = totalRecord % pageSize == 0 ? totalRecord / pageSize : (totalRecord / pageSize) + 1; } return totalPage; } public void setTotalPage(int totalPage) { this.totalPage = totalPage; } public int getStartIndex() { return startIndex; } public void setStartIndex(int startIndex) { this.startIndex = startIndex; } public int getEndIndex() { return endIndex; } public void setEndIndex(int endIndex) { this.endIndex = endIndex; } public int getGroupSize() { if (groupSize <= 0) { groupSize = 10; } return groupSize; } public void setGroupSize(int groupSize) { this.groupSize = groupSize; } public int getLeftOffset() { leftOffset = getGroupSize() / 2; return leftOffset; } public void setLeftOffset(int leftOffset) { this.leftOffset = leftOffset; } public int getRightOffset() { int groupSize = getGroupSize(); if (groupSize % 2 == 0) { rightOffset = (groupSize / 2) - 1; } else { rightOffset = groupSize / 2; } return rightOffset; } public void setRightOffset(int rightOffset) { this.rightOffset = rightOffset; } /** 中心位置索引[从1开始计算] */ public int getMiddleOffset() { int groupSize = getGroupSize(); int totalPage = getTotalPage(); if (groupSize >= totalPage) { return -1; } return getLeftOffset() + 1; } public String[] getPageRange() { setRangeIndex(); int size = endIndex - startIndex + 1; if (size <= 0) { return new String[0]; } if (totalPage == 1) { return new String[] { "1" }; } pageRange = new String[size]; for (int i = 0; i < size; i++) { pageRange[i] = (startIndex + i + 1) + ""; } return pageRange; } public void setPageRange(String[] pageRange) { this.pageRange = pageRange; } public Collection<T> getItems() { return items; } public void setItems(Collection<T> items) { this.items = items; } public List<Document> getDocList() { return docList; } public void setDocList(List<Document> docList) { this.docList = docList; } public ScoreDoc getAfterDoc() { setAfterDocId(afterDocId); return afterDoc; } public void setAfterDoc(ScoreDoc afterDoc) { this.afterDoc = afterDoc; } public int getAfterDocId() { return afterDocId; } public void setAfterDocId(int afterDocId) { this.afterDocId = afterDocId; if (null == afterDoc) { this.afterDoc = new ScoreDoc(afterDocId, 1.0f); } } public Page() { } public Page(int currentPage, int pageSize) { this.currentPage = currentPage; this.pageSize = pageSize; } public Page(int currentPage, int pageSize, Collection<T> items) { this.currentPage = currentPage; this.pageSize = pageSize; this.items = items; } public Page(int currentPage, int pageSize, Collection<T> items, int groupSize) { this.currentPage = currentPage; this.pageSize = pageSize; this.items = items; this.groupSize = groupSize; } public Page(int currentPage, int pageSize, int groupSize, int afterDocId) { this.currentPage = currentPage; this.pageSize = pageSize; this.groupSize = groupSize; this.afterDocId = afterDocId; } public static void main(String[] args) { Collection<Integer> items = new ArrayList<Integer>(); int totalRecord = 201; for (int i = 0; i < totalRecord; i++) { items.add(new Integer(i)); } Page<Integer> page = new Page<Integer>(1, 10, items, 10); page.setTotalRecord(totalRecord); int totalPage = page.getTotalPage(); for (int i = 0; i < totalPage; i++) { page.setCurrentPage(i + 1); String[] pageRange = page.getPageRange(); System.out.println("当前第" + page.currentPage + "页"); for (int j = 0; j < pageRange.length; j++) { System.out.print(pageRange[j] + " "); } System.out.println("\n"); } } }
接下来我们测试一下
package com.think3c.lucene.index; import java.io.IOException; import org.apache.lucene.document.Document; import org.apache.lucene.queryparser.classic.ParseException; import org.junit.Test; /** * lucene 5.3.1 * http://janle.iteye.com/blog/2254370 * @author Janle * */ public class SearchTest { @Test public void TestqueryPage(){ //参数定义 String indexPath = "你的索引路径"; String fieldName = "contents"; String queryString = "scripts"; int currentPage = 1; int pageSize = 10; Page<Document> page; try { page = IndexSearch.pageQuery(fieldName, queryString, indexPath, currentPage, pageSize); if(page == null || page.getItems() == null || page.getItems().size() == 0) { System.out.println("没有搜到"); return; } for(Document doc : page.getItems()) { String path = doc.get("path"); String content = doc.get("contents"); System.out.println("path:" + path); System.out.println("contents:" + content); } } catch (ParseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
直接运行测试就好
代码就不解释了,上边有注释。