转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/44279753
http://www.llwjy.com/blogdetail/31bb705106379feaf6d31b58dd777be6.html
个人博客小站搭建成功,网址 www.llwjy.com,欢迎大家来吐槽~
在前面的博客中,我们已经介绍了IndexSearcher中的检索方法,也介绍了如何基于lucene中的NRT*类去创建实时索引,在这篇博客中我们就重点介绍下基于实时索引的检索方案。在开始介绍之前,我们首先定一下检索结果的数据结构(这样做的好处是无论是什么检索,得到的数据结构都是一样的,方便以后的处理~)
原来我长这样
检索结果的数据结构主要包括两个字段,如下:
private int count; private List<Document> datas;
/** * @Description: 索引搜索结果数据结构 */ package com.lulei.lucene.index.model; import java.util.List; import org.apache.lucene.document.Document; public class SearchResultBean { private int count; private List<Document> datas; public int getCount() { return count; } public void setCount(int count) { this.count = count; } public List<Document> getDatas() { return datas; } public void setDatas(List<Document> datas) { this.datas = datas; } }
检索结果介绍完了,下面就看下如何基于上次博客中的实时索引去检索数据,不知还记得上篇博客中封装的getIndexSearcher()方法(如果忘记了,看下该系列的前一篇博客),这个方法提供了当前最新可用的IndexSearcher对象,索引我们再去检索的时候,直接调用该方法即可。IndexManager类实现了另类的单例模式,使用了索引名来标识IndexManager,因此我们在写检索基类的时候,需要添加一个构造方法,如下:
public NRTSearch(String indexName) { indexManager = IndexManager.getIndexManager(indexName); }在NRTSearch类中,我们主要封装4个方法:
1.public int getIndexNum(){} 2.public SearchResultBean search(Query query, int start, int end){} 3.public SearchResultBean search(Query query, int start, int end, Sort sort){} 4.public SearchResultBean search(int start, int count){}在四个方法分别实现:
1.获取索引中的记录条数;
2.根据query查询索引,根据相关读排序,返回[start, end)记录;
3.根据query查询索引,根据指定sort排序,返回[start, end)记录;
4:从索引中的第start条开始,获取后面的count条记录(如果start + count 大于索引中的记录总条数,则从头补齐)。
这四个方法已经可以实现了80%的站内搜索功能,如果还有其他复杂的,可以根据实际情况来拓展,NRTSearch类源代码如下:
/** * @Description: 索引的查询操作 */ package com.lulei.lucene.index.operation; import java.util.ArrayList; import java.util.List; import org.apache.lucene.document.Document; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.Sort; import org.apache.lucene.search.TopDocs; import com.lulei.lucene.index.manager.IndexManager; import com.lulei.lucene.index.model.SearchResultBean; public class NRTSearch { private IndexManager indexManager; /** * @param indexName 索引名 */ public NRTSearch(String indexName) { indexManager = IndexManager.getIndexManager(indexName); } /** * @return * @Author:lulei * @Description: 索引中的记录数量 */ public int getIndexNum() { return indexManager.getIndexNum(); } /** * @param query 查询字符串 * @param start 起始位置 * @param end 结束位置 * @author lulei * @return 查询结果 */ public SearchResultBean search(Query query, int start, int end) { start = start < 0 ? 0 : start; end = end < 0 ? 0 : end; if (indexManager == null || query == null || start >= end) { return null; } SearchResultBean result = new SearchResultBean(); List<Document> datas = new ArrayList<Document>(); result.setDatas(datas); IndexSearcher searcher = indexManager.getIndexSearcher(); try { TopDocs docs = searcher.search(query, end); result.setCount(docs.totalHits); end = end > docs.totalHits ? docs.totalHits : end; for (int i = start; i < end; i++) { datas.add(searcher.doc(docs.scoreDocs[i].doc)); } } catch (Exception e) { e.printStackTrace(); } finally { indexManager.release(searcher); } return result; } /** * @param query 查询字符串 * @param start 起始位置 * @param end 结束位置 * @param sort 排序条件 * @return 查询结果 */ public SearchResultBean search(Query query, int start, int end, Sort sort) { start = start < 0 ? 0 : start; end = end < 0 ? 0 : end; if (indexManager == null || query == null || start >= end) { return null; } SearchResultBean result = new SearchResultBean(); List<Document> datas = new ArrayList<Document>(); result.setDatas(datas); IndexSearcher searcher = indexManager.getIndexSearcher(); try { TopDocs docs = searcher.search(query, end, sort); result.setCount(docs.totalHits); end = end > docs.totalHits ? docs.totalHits : end; for (int i = start; i < end; i++) { datas.add(searcher.doc(docs.scoreDocs[i].doc)); } } catch (Exception e) { e.printStackTrace(); } finally { indexManager.release(searcher); } return result; } /** * @param start * @param count * @return * @Author:lulei * @Description: 按序号检索 */ public SearchResultBean search(int start, int count) { start = start < 0 ? 0 : start; count = count < 0 ? 0 : count; if (indexManager == null) { return null; } SearchResultBean result = new SearchResultBean(); List<Document> datas = new ArrayList<Document>(); result.setDatas(datas); IndexSearcher searcher = indexManager.getIndexSearcher(); result.setCount(count); try { for (int i = 0; i < count; i++) { datas.add(searcher.doc((start + i) % getIndexNum())); } } catch (Exception e) { e.printStackTrace(); } finally { indexManager.release(searcher); } return result; } }到这里为止,NRTSearch类就介绍完毕了,之后就可以根据实际的应用来创建子类,实现一系列的查询操作,如:关键字检索、分类检索、标签检索、作者检索等等,在之后的应用中在继续介绍。
ps:最近发现其他网站可能会对博客转载,上面并没有源链接,如想查看更多关于
基于lucene的案例开发 请点击这里。或访问网址http://blog.csdn.net/xiaojimanman/article/category/2841877 或 http://www.llwjy.com/
原文地址:http://blog.csdn.net/xiaojimanman/article/details/44279753