轉載請注明出處:[http://blog.csdn.net/xiaojimanman/article/details/44279753](http://blog.csdn.net/xiaojimanman/article/details/44279753)
[http://www.llwjy.com/blogdetail/31bb705106379feaf6d31b58dd777be6.html](http://www.llwjy.com/blogdetail/31bb705106379feaf6d31b58dd777be6.html)
個人博客小站搭建成功,網址 [www.llwjy.com](http://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://www.llwjy.com/blogtype/lucene.html)? 請[點擊這里](http://blog.csdn.net/xiaojimanman/article/category/2841877)。或訪問網址http://blog.csdn.net/xiaojimanman/article/category/2841877 或 http://www.llwjy.com/
- 前言
- 寫在開始之前
- lucene初始認知
- 索引數學模型
- 索引文件結構
- 創建索引
- 搜索索引
- 分詞器介紹
- Query查詢
- IndexSearcher中檢索方法
- 更新說明
- 案例初識
- JsonUtil &amp; XmlUtil
- 基ClassUtil &amp; CharsetUtil
- ParseUtil &amp; ParseRequest
- 數據庫連接池
- 實現實時索引基本原理
- 實時索引管理類IndexManager
- 實時索引的檢索
- 實時索引的修改
- 查詢語句創建PackQuery
- 縱橫小說更新列表頁抓取
- 縱橫小說簡介頁采集
- 縱橫小說章節列表采集
- 縱橫小說閱讀頁采集
- 縱橫小說數據庫設計
- 縱橫小說數據庫操作
- 縱橫小說分布式采集