- 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,或者加裙:
,欢迎你加入一起交流学习。
转载:http://iamyida.iteye.com/blog/2193345