上篇博文《Lucene5学习之创建索引入门示例》里我们创建了索引,现在我们来编写测试代码来查询索引,具体代码如下:
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<Document> 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<Document> 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<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 currentPage * @param pageSize * @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; } /** * @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<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"); } } }
来张运行效果图大家感受下:
demo源代码请在附件里下载,千言万语都在代码中,你们懂的。
若你还有什么疑问,请加我Q-Q:7-3-6-0-3-1-3-0-5,或者加裙:
,欢迎你加入一起交流学习。
相关推荐
一步一步跟我学习lucene是对近期做lucene索引的总结,大家有问题的话联系本人如蒙加入,不胜感激,大家共同探讨,本人争取每日一博,希望大家持续关注,会带给大家惊喜的
2.4 查询索引的基本信息 5 2.5 删除和更新索引 5 (1) 使用writer删除 5 (2) 使用reader删除 5 (3) 恢复删除 5 (4) 彻底删除 6 (5) 更新索引 6 (6) 手动优化 6 2.6 索引文件作用 7 第三章 搜索功能 8 3.1 简单搜索 8 ...
lucene4.8学习资料和案例,自己学习整理。整理了各种查询,包括分页、排序等!对100W,500W,1000W三个级别的数据量分别进行了测试!
介绍lucene3.5的相关技术,包括基本用法、分析器、索引建立与查询,扩展的高亮、分页、以及solr3.5的相关用法
lucene4.,4事例,包含lucene4.4的增删改查,分页查询,适合更开始接触搜索引擎的朋友参考,下载了包你不后悔,因为我也是初学者,根据一些资源学习后,自己写的,适合大家参考
NULL 博文链接:https://hellotommy.iteye.com/blog/826318
基本可以满足 检索电脑内文件的需求了 已经封装过了 直接指定检索目录和索引目录来创建索引.提供给学习者门参考... 直接通过调用静态方法来实现 深度分页检索.
该书详细讲解了搜索引擎与信息检索基础,Lucene入门实例,Lucene索引的建立,使用Lucene进行搜索,排序,过滤和分页,Lucene的分析器,对Word、Excel和PDF格式文档的处理,Compass搜索引擎框架,Lucene分布式和...
一、2012版关键字标签[@cms_tag_list] 二、2012版搜索结果分页标签[@cms_lucene_page] 三、2012版页面模板包含标签[@cms_Include] 四、2012版留言列表标签[@cms_guestbook_list] ...
暑假学习ssm架构的时候,花了半个月写的一款博客系统,页面展示如下后台 功能 后台 文章管理 友链管理 公告管理 评论管理 用户管理 链接管理 后台其他设置 前台 浏览文章 文章分类查找 文章标签查找 按关键字搜索...
系统设计 1 jive设计思路 2 jive的工作内幕 3 Jive源代码研究 4 Jive中的设计模式 5 jive学习笔记 <br> 设计模式 1 大道至简-Java之23种模式一点就通 2 设计模式...
系统设计 1 jive设计思路 2 jive的工作内幕 3 Jive源代码研究 4 Jive中的设计模式 5 jive学习笔记 <br> <br> 数据库设计 1 Jive Forums数据库说明(英文) 2 Jive KB...
│ 12-MySQL的查询优化.avi │ 13-数据库结构优化.avi │ 14-插入数据的优化.avi │ 15-服务器优化.avi │ 16-tomcat的3种运行模式和执行器(线程池).avi │ 17-tomcat中连接器.avi │ 18-禁用AJP连接器.avi │ 19-...
5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...
数据库开发基础、Microsoft SQLServer基础、SQL语言基础、索引、事务、SQL语言高级技术(空值处理、聚合与分组、数据分页、Union、日期函数、类型转换函数、流控函数、表连接、子查询、存储过程、触发器)、数据库...
5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...