博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lucene5学习之分页查询
阅读量:4027 次
发布时间:2019-05-24

本文共 10787 字,大约阅读时间需要 35 分钟。

    上篇博文里我们创建了索引,现在我们来编写测试代码来查询索引,具体代码如下:

    

package com.yida.framework.lucene5.core;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;import com.yida.framework.lucene5.util.Page;/** * Lucene搜索第一个示例 * @author Lanxiaowei * */public class SearchFirstTest {	public static void main(String[] args) throws ParseException, IOException {		//参数定义		String directoryPath = "D:/lucenedir";		String fieldName = "contents";		String queryString = "mount";		int currentPage = 1;		int pageSize = 10;				Page
page = pageQuery(fieldName, queryString, directoryPath, currentPage, pageSize); if(page == null || page.getItems() == null || page.getItems().size() == 0) { System.out.println("No results found."); 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); } } /** * 创建索引阅读器 * @param directoryPath 索引目录 * @return * @throws IOException 可能会抛出IO异常 */ public static IndexReader createIndexReader(String directoryPath) throws IOException { return DirectoryReader.open(FSDirectory.open(Paths.get(directoryPath, new String[0]))); } /** * 创建索引查询器 * @param directoryPath 索引目录 * @return * @throws IOException */ public static IndexSearcher createIndexSearcher(String directoryPath) throws IOException { return new IndexSearcher(createIndexReader(directoryPath)); } /** * 创建索引查询器 * @param reader * @return */ public static IndexSearcher createIndexSearcher(IndexReader reader) { return new IndexSearcher(reader); } /** * Lucene分页查询 * @param directoryPath * @param query * @param page * @throws IOException */ public static void pageQuery(String directoryPath,Query query,Page
page) throws IOException { IndexSearcher searcher = createIndexSearcher(directoryPath); int totalRecord = searchTotalRecord(searcher,query); //设置总记录数 page.setTotalRecord(totalRecord); TopDocs topDocs = searcher.searchAfter(page.getAfterDoc(),query, page.getPageSize()); List
docList = new ArrayList
(); 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 currentPage * @param pageSize * @throws ParseException * @throws IOException */ public static Page
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
page = new Page
(currentPage,pageSize); pageQuery(directoryPath, query, page); return page; } /** * @Title: searchTotalRecord * @Description: 获取符合条件的总记录数 * @param query * @return * @throws IOException */ public 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; }}

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

    

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里你打开索引目录是这样的:

FSDirectory.open(directoryPath);

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

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

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

 

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

package com.yida.framework.lucene5.util;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
{ /**当前第几页(从1开始计算)*/ private int currentPage; /**每页显示几条*/ private int pageSize; /**总记录数*/ private int totalRecord; /**总页数*/ private int totalPage; /**分页数据集合[用泛型T来限定集合元素类型]*/ private Collection
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
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
getItems() { return items; } public void setItems(Collection
items) { this.items = items; } public List
getDocList() { return docList; } public void setDocList(List
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
items) { this.currentPage = currentPage; this.pageSize = pageSize; this.items = items; } public Page(int currentPage, int pageSize, Collection
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
items = new ArrayList
(); int totalRecord = 201; for(int i=0; i < totalRecord; i++) { items.add(new Integer(i)); } Page
page = new Page
(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"); } }}

 

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

 

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

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

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

 

转载地址:http://obxbi.baihongyu.com/

你可能感兴趣的文章
AsyncTask、View.post(Runnable)、ViewTreeObserver三种方式总结frame animation自动启动
查看>>
Android中AsyncTask的简单用法
查看>>
S3C6410启动模式介绍
查看>>
Jlink + ADS调试 S3C2440
查看>>
2440初始化存储器原理(接上一篇)
查看>>
S3C2440 USB 设备控制器(转)
查看>>
Linux usb 设备驱动 (1)
查看>>
解决跨网场景下,CAS重定向无法登录的问题(无需修改现有代码)
查看>>
java反编译命令
查看>>
activemq依赖包获取
查看>>
概念区别
查看>>
关于静态块、静态属性、构造块、构造方法的执行顺序
查看>>
final 的作用
查看>>
在Idea中使用Eclipse编译器
查看>>
idea讲web项目部署到tomcat,热部署
查看>>
优化IDEA启动速度,快了好多。后面有什么优化点,会继续往里面添加
查看>>
JMeter 保持sessionId
查看>>
IDEA Properties中文unicode转码问题
查看>>
Idea下安装Lombok插件
查看>>
zookeeper
查看>>