lucene 查询+分页+排序
来源:互联网 发布:linux命令是什么 编辑:程序博客网 时间:2024/05/17 08:54
1、定义一个工厂类
LuceneFactory
import java.io.IOException; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.apache.lucene.util.Version; import org.wltea.analyzer.lucene.IKAnalyzer; import cn.utils.Constant; public class LuceneFactory { private static IndexReader fileReader = null; private static Directory fileDirectory = null; private static IndexWriter fileWriter = null; public static Analyzer ana = new IKAnalyzer(); /** * 获取indexwriter * @return * @throws IOException */ public static synchronized IndexWriter getFileWrite() throws IOException { if(fileWriter == null){ fileDirectory = FSDirectory.open(Constant.file_index_path_File); if (IndexWriter.isLocked(fileDirectory)) { IndexWriter.unlock(fileDirectory); } fileWriter = new IndexWriter(fileDirectory, new IndexWriterConfig(Version.LUCENE_36, ana)); return fileWriter; } System.out.println("filewriter != null"); return fileWriter; } /** *获得IndexReader对象,判断是否为最新,不是则重新打开 *@param file 索引路径的File对象 **/ public static synchronized IndexReader getFileRead() throws IOException { if (fileReader == null) { fileDirectory = FSDirectory.open(Constant.file_index_path_File); fileReader = IndexReader.open(fileDirectory); } else { if (!fileReader.isCurrent()) { fileReader = IndexReader.openIfChanged(fileReader); } } return fileReader; } /*** * 获得IndexSearcher对象,判断当前的Searcher中reader是否为最新,如果不是,则重新创建IndexSearcher * * @return * @throws IOException */ public static synchronized IndexSearcher getFileSearch() throws IOException { /*if (fileSearcher == null) { fileDirectory = FSDirectory.open(file_index_path); fileSearcher = new IndexSearcher(IndexReader.open(fileDirectory)); } else { IndexReader r = fileSearcher.getIndexReader(); if (!r.isCurrent()) { fileSearcher.close(); fileSearcher = new IndexSearcher(IndexReader.openIfChanged(r)); } } return fileSearcher;*/ return new IndexSearcher(getFileRead()); } public static void closeFileWrite() { if(fileWriter != null) { try { fileWriter.commit(); fileWriter.close(); } catch (CorruptIndexException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } }
2、定义返回结果bean
import java.util.List; import org.apache.lucene.document.Document; public class SearchResultBean { private int totalHits; private List<Document> docs; public SearchResultBean() { } public SearchResultBean(int totalHits, List<Document> docs) { this.totalHits = totalHits; this.docs = docs; } public int getTotalHits() { return this.totalHits; } public void setTotalHits(int totalHits) { this.totalHits = totalHits; } public List<Document> getDocs() { return this.docs; } public void setDocs(List<Document> docs) { this.docs = docs; } }
3、分页bean
import java.util.ArrayList;import java.util.List;public class PageBean{ private int currentPage = 1;// 当前页数 private int totalPages = 0;// 总页数 private int pageSize = 0;// 每页显示数 private int totalRows = 0;// 总数据数 private int startNum = 0;// 开始记录 private int nextPage = 0;// 下一页 private int previousPage = 0;// 上一页 private boolean hasNextPage = false;// 是否有下一页 private boolean hasPreviousPage = false;// 是否有前一页 private List<String> pageCodes; private int showPageSize = 8; //显示多少个超链接页面 public PageBean() {} public PageBean(int pageSize, int currentPage, int totalRows) { this.pageSize = pageSize; this.currentPage = currentPage; this.totalRows = totalRows; if ((totalRows % pageSize) == 0) { totalPages = totalRows / pageSize; } else { totalPages = totalRows / pageSize + 1; } if (currentPage >= totalPages) { hasNextPage = false; currentPage = totalPages; } else { hasNextPage = true; } if (currentPage <= 1) { hasPreviousPage = false; currentPage = 1; } else { hasPreviousPage = true; } startNum = (currentPage - 1) * pageSize; nextPage = currentPage + 1; if (nextPage >= totalPages) { nextPage = totalPages; } previousPage = currentPage - 1; if (previousPage <= 1) { previousPage = 1; } reflashPageCode(); } public void reflashPageCode() { this.pageCodes = new ArrayList<String>(); if (this.totalPages <= this.showPageSize) { for (int i = 1; i <= this.totalPages; i++) { this.pageCodes.add(String.valueOf(i)); } return; } int middleSide = this.showPageSize >> 1; if (this.currentPage <= middleSide) { for (int i = 1; i <= this.showPageSize; i++) { this.pageCodes.add(String.valueOf(i)); } this.pageCodes.add(String.valueOf("..")); return; } if ((this.totalPages - this.currentPage) <= middleSide) { this.pageCodes.add(String.valueOf("..")); for (int i = this.showPageSize - 1; i >= 0; i--) { this.pageCodes.add(String.valueOf(this.totalPages - i)); } return; } if (middleSide < this.currentPage && this.currentPage - (middleSide + 1) > 0) this.pageCodes.add(String.valueOf("..")); for (int i = 0; i < this.showPageSize; i++) { this.pageCodes.add(String.valueOf((this.currentPage + i) - middleSide)); } if (middleSide > this.currentPage || this.totalPages - (this.currentPage + middleSide) > 0) this.pageCodes.add(String.valueOf("..")); } public boolean isHasNextPage() { return hasNextPage; } public boolean isHasPreviousPage() { return hasPreviousPage; } /** * @return the nextPage */ public int getNextPage() { return nextPage; } /** * @param nextPage * the nextPage to set */ public void setNextPage(int nextPage) { this.nextPage = nextPage; } /** * @return the previousPage */ public int getPreviousPage() { return previousPage; } /** * @param previousPage * the previousPage to set */ public void setPreviousPage(int previousPage) { this.previousPage = previousPage; } /** * @return the currentPage */ public int getCurrentPage() { return currentPage; } /** * @param currentPage * the currentPage to set */ public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } /** * @return the pageSize */ public int getPageSize() { return pageSize; } /** * @param pageSize * the pageSize to set */ public void setPageSize(int pageSize) { this.pageSize = pageSize; } /** * @return the totalPages */ public int getTotalPages() { return totalPages; } /** * @param totalPages * the totalPages to set */ public void setTotalPages(int totalPages) { this.totalPages = totalPages; } /** * @return the totalRows */ public int getTotalRows() { return totalRows; } /** * @param totalRows * the totalRows to set */ public void setTotalRows(int totalRows) { this.totalRows = totalRows; } /** * @param hasNextPage * the hasNextPage to set */ public void setHasNextPage(boolean hasNextPage) { this.hasNextPage = hasNextPage; } /** * @param hasPreviousPage * the hasPreviousPage to set */ public void setHasPreviousPage(boolean hasPreviousPage) { this.hasPreviousPage = hasPreviousPage; } /** * @return the startNum */ public int getStartNum() { return startNum; } /** * @param startNum * the startNum to set */ public void setStartNum(int startNum) { this.startNum = startNum; } public List<String> getPageCodes() { if (this.pageCodes == null) { return new ArrayList<String>(); } return pageCodes; } public void setPageCodes(List<String> pageCodes) { this.pageCodes = pageCodes; } public int getShowPageSize() { return showPageSize; } public void setShowPageSize(int showPageSize) { this.showPageSize = showPageSize; } }
4、搜索方法 重点
/**** * 命名不是很好 * @param field:暂时么用 * @param query:query * @param first:分页起始值,如第一页0, first 0 max 20,第二页 first20, max 20 * @param max:每页显示的数目,如20 * @param sort:排序 * @param highLight:是否高亮,这里不咱贴代码 * @return */ public static SearchResultBean searchAndSort(String field, Query query, int first, int max, Sort sort, boolean highLight) { if(query == null){ System.out.println(" Query is null return null "); return null; } try { List<Document> docs = new ArrayList<Document>(); IndexSearcher searcher = LuceneFactory.getFileSearch(); TopFieldCollector c = TopFieldCollector.create(sort, first+max, false, false, false, false); searcher.search(query, c); ScoreDoc[] hits = c.topDocs(first, max).scoreDocs; if (hits == null || hits.length < 1) return null; // 高亮------------------------------ Formatter htmlFormatter = null; if (highLight) htmlFormatter = new SimpleHTMLFormatter( "<span style='color:red;'>", "</span>"); else htmlFormatter = new SimpleHTMLFormatter("", ""); Scorer scorer = new QueryScorer(query); //Encoder encoder = new SimpleHTMLEncoder(); Fragmenter fragmenter = new SimpleFragmenter(Max_Match_Num); Highlighter highlighter = new Highlighter(htmlFormatter, scorer); highlighter.setTextFragmenter(fragmenter); for (int i = 0; i < hits.length; i++) { Document doc = searcher.doc(hits[i].doc); highlight(highlighter, doc, field); docs.add(doc); } return new SearchResultBean(c.getTotalHits(), docs); } catch (Exception e) { return null; } }
- 第23行,max+first 值无所谓,返回的是命中数,不会是一个list集合,不用担心内存开销
- 第38行,中文分词、做高亮的时候,不注释这段代码,高亮的结果是unicode编码,搞不懂,暂时没研究。我用IK分词,测试与IK无关。
- 第51行, c.getTotalHits(),回到第一个问题,就是lucene分页,以前做数据库分页的时候,需要查询2次,而lucene只需要一次就OK。
分页jsp页面
<%@ page language="java" pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%><%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%><script type="text/javascript" src="${pageContext.request.contextPath}/script/jquery.js"></script><div class="pagelistbox"> <input type="hidden" name="currentPage" id="currentPage" value="${pager.currentPage}" /> <span>共 ${pager.totalPages} 页/${pager.totalRows}条记录 </span> <c:if test="${pager.hasPreviousPage}"> <span class="indexPage"> <a href="${pageContext.request.contextPath}/${page_url}1">首页</a></span> </c:if> <c:forEach var="every" items="${pager.pageCodes}"> <c:choose> <c:when test="${every ne fn:trim(pager.currentPage) && every eq '..'}"> <span>${every} </span> </c:when> <c:when test="${every ne fn:trim(pager.currentPage)}"> <a href="${pageContext.request.contextPath}/${page_url}${every}">${every}</a> </c:when> <c:otherwise> <strong>${every}</strong> </c:otherwise> </c:choose> </c:forEach> <c:if test="${pager.hasNextPage}"> <a class="nextPage" href="${pageContext.request.contextPath}/${page_url}${pager.nextPage}">下页</a> <a class="nextPage" href="${pageContext.request.contextPath}/${page_url}${pager.totalPages}">末页</a> </c:if></div>
0 0
- lucene 查询+分页+排序
- lucene查询索引库、分页、过滤、排序、高亮
- java鬼混笔记:lucene 7、查询排序和分页
- Lucene的分页查询
- Lucene的分页查询
- lucene分页查询
- Lucene分页查询
- Lucene 分页排序
- lucene 排序 分页
- Lucene 的查询方式|排序
- 数据库分页查询+排序
- 分页查询,并且排序
- Redis 分页排序查询
- Redis分页排序查询
- mongodb排序&分页查询
- oracle分页排序查询
- Lucene代码备份之分页条件查询
- SQL 查询分页,排序后分页查询
- “基于485总线的评分系统”
- 【28系列DSP小结-2】cmd文件
- wpa_supplicant summary
- iOS的基本的设计模式
- 设计模式-----门面模式
- lucene 查询+分页+排序
- struts2前台向后台传递map
- Oracle阻塞(blockingblocked)实例详解
- web.xml中url-pattern配置了/ 静态页面404
- scrollview 嵌套listview、gridview 各种奇葩问题
- 如尼文字(卢恩字母)全解
- 设计模式-----桥接模式
- Python的 函数 参数为数据结构和表的区别
- QML概念及框架--QML属性