分享

基于lucene的案例开发15:实时索引的检索

gefieder 2015-4-14 17:07:53 发表于 连载型 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 0 16644
本帖最后由 nettman 于 2015-4-16 22:38 编辑
问题导读:
1、检索结果的数据结构是怎样的?
2、如何利用实时索引去检索数据?
3、利用NRTSearch类如何实现一系列的查询操作:如,关键字检索,分类检索等?




接上篇:基于lucene的案例开发14:实时索引管理类IndexManager

在前面的博客中,我们已经介绍了IndexSearcher中的检索方法,也介绍了如何基于lucene中的NRT*类去创建实时索引,在这篇博客中我们就重点介绍下基于实时索引的检索方案。在开始介绍之前,我们首先定一下检索结果的数据结构(这样做的好处是无论是什么检索,得到的数据结构都是一样的,方便以后的处理~)


原来我长这样

      检索结果的数据结构主要包括两个字段,如下:

  1.     private int count;  
  2.     private List<Document> datas;  
复制代码
     这两个字段分别代表着该检索条件下的符合条件的记录条数和本次查询到的记录数组(该记录是索引中的记录),因此检索结果类源代码如下:
  1.     /**
  2.      * @Description:  索引搜索结果数据结构
  3.      */  
  4.     package com.lulei.lucene.index.model;  
  5.       
  6.     import java.util.List;  
  7.       
  8.     import org.apache.lucene.document.Document;  
  9.       
  10.     public class SearchResultBean {  
  11.         private int count;  
  12.         private List<Document> datas;  
  13.          
  14.         public int getCount() {  
  15.             return count;  
  16.         }  
  17.         public void setCount(int count) {  
  18.             this.count = count;  
  19.         }  
  20.         public List<Document> getDatas() {  
  21.             return datas;  
  22.         }  
  23.         public void setDatas(List<Document> datas) {  
  24.             this.datas = datas;  
  25.         }  
  26.     }  
复制代码
检索原来如此简单

      检索结果介绍完了,下面就看下如何基于上次博客中的实时索引去检索数据,不知还记得上篇博客中封装的getIndexSearcher()方法(如果忘记了,看下该系列的前一篇博客),这个方法提供了当前最新可用的IndexSearcher对象,索引我们再去检索的时候,直接调用该方法即可。IndexManager类实现了另类的单例模式,使用了索引名来标识IndexManager,因此我们在写检索基类的时候,需要添加一个构造方法,如下:

  1. public NRTSearch(String indexName) {
  2. indexManager = IndexManager.getIndexManager(indexName);
  3. }
复制代码

     在NRTSearch类中,我们主要封装4个方法:

  1.     1.public int getIndexNum(){}  
  2.     2.public SearchResultBean search(Query query, int start, int end){}  
  3.     3.public SearchResultBean search(Query query, int start, int end, Sort sort){}  
  4.     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类源代码如下:

  1.     /**
  2.      * @Description:  索引的查询操作
  3.      */  
  4.     package com.lulei.lucene.index.operation;  
  5.       
  6.     import java.util.ArrayList;  
  7.     import java.util.List;  
  8.       
  9.     import org.apache.lucene.document.Document;  
  10.     import org.apache.lucene.search.IndexSearcher;  
  11.     import org.apache.lucene.search.Query;  
  12.     import org.apache.lucene.search.Sort;  
  13.     import org.apache.lucene.search.TopDocs;  
  14.       
  15.     import com.lulei.lucene.index.manager.IndexManager;  
  16.     import com.lulei.lucene.index.model.SearchResultBean;  
  17.       
  18.     public class NRTSearch {  
  19.         private IndexManager indexManager;  
  20.          
  21.         /**
  22.          * @param indexName 索引名
  23.          */  
  24.         public NRTSearch(String indexName) {  
  25.             indexManager = IndexManager.getIndexManager(indexName);  
  26.         }  
  27.          
  28.         /**
  29.          * @return
  30.          * @Author:lulei   
  31.          * @Description: 索引中的记录数量
  32.          */  
  33.         public int getIndexNum() {  
  34.             return indexManager.getIndexNum();  
  35.         }  
  36.          
  37.         /**
  38.          * @param query 查询字符串
  39.          * @param start 起始位置
  40.          * @param end 结束位置
  41.          * @author lulei
  42.          * @return 查询结果
  43.          */  
  44.         public SearchResultBean search(Query query, int start, int end) {  
  45.             start = start < 0 ? 0 : start;  
  46.             end = end < 0 ? 0 : end;  
  47.             if (indexManager == null || query == null || start >= end) {  
  48.                 return null;  
  49.             }  
  50.             SearchResultBean result = new SearchResultBean();  
  51.             List<Document> datas = new ArrayList<Document>();  
  52.             result.setDatas(datas);  
  53.             IndexSearcher searcher = indexManager.getIndexSearcher();  
  54.             try {  
  55.                 TopDocs docs = searcher.search(query, end);  
  56.                 result.setCount(docs.totalHits);  
  57.                 end = end > docs.totalHits ? docs.totalHits : end;  
  58.                 for (int i = start; i < end; i++) {  
  59.                     datas.add(searcher.doc(docs.scoreDocs[i].doc));  
  60.                 }  
  61.             } catch (Exception e) {  
  62.                 e.printStackTrace();  
  63.             } finally {  
  64.                 indexManager.release(searcher);  
  65.             }  
  66.             return result;  
  67.         }  
  68.          
  69.         /**
  70.          * @param query 查询字符串
  71.          * @param start 起始位置
  72.          * @param end 结束位置
  73.          * @param sort 排序条件
  74.          * @return 查询结果
  75.          */  
  76.         public SearchResultBean search(Query query, int start, int end, Sort sort) {  
  77.             start = start < 0 ? 0 : start;  
  78.             end = end < 0 ? 0 : end;  
  79.             if (indexManager == null || query == null || start >= end) {  
  80.                 return null;  
  81.             }  
  82.             SearchResultBean result = new SearchResultBean();  
  83.             List<Document> datas = new ArrayList<Document>();  
  84.             result.setDatas(datas);  
  85.             IndexSearcher searcher = indexManager.getIndexSearcher();  
  86.             try {  
  87.                 TopDocs docs = searcher.search(query, end, sort);  
  88.                 result.setCount(docs.totalHits);  
  89.                 end = end > docs.totalHits ? docs.totalHits : end;  
  90.                 for (int i = start; i < end; i++) {  
  91.                     datas.add(searcher.doc(docs.scoreDocs[i].doc));  
  92.                 }  
  93.             } catch (Exception e) {  
  94.                 e.printStackTrace();  
  95.             } finally {  
  96.                 indexManager.release(searcher);  
  97.             }  
  98.             return result;  
  99.         }  
  100.          
  101.         /**
  102.          * @param start
  103.          * @param count
  104.          * @return
  105.          * @Author:lulei   
  106.          * @Description: 按序号检索
  107.          */  
  108.         public SearchResultBean search(int start, int count) {  
  109.             start = start < 0 ? 0 : start;  
  110.             count = count < 0 ? 0 : count;  
  111.             if (indexManager == null) {  
  112.                 return null;  
  113.             }  
  114.             SearchResultBean result = new SearchResultBean();  
  115.             List<Document> datas = new ArrayList<Document>();  
  116.             result.setDatas(datas);  
  117.             IndexSearcher searcher = indexManager.getIndexSearcher();  
  118.             result.setCount(count);  
  119.             try {  
  120.                 for (int i = 0; i < count; i++) {  
  121.                     datas.add(searcher.doc((start + i) % getIndexNum()));  
  122.                 }  
  123.             } catch (Exception e) {  
  124.                 e.printStackTrace();  
  125.             } finally {  
  126.                 indexManager.release(searcher);  
  127.             }  
  128.             return result;  
  129.         }  
  130.     }  
复制代码
到这里为止,NRTSearch类就介绍完毕了,之后就可以根据实际的应用来创建子类,实现一系列的查询操作,如:关键字检索、分类检索、标签检索、作者检索等等,在之后的应用中在继续介绍。





相关内容:
基于lucene的案例开发1:lucene初始认知

基于lucene的案例开发2:索引数学模型

基于lucene的案例开发3:索引文件结构

基于lucene的案例开发4:创建索引

基于lucene的案例开发5:搜索索引

基于lucene的案例开发6:分词器介绍

基于lucene的案例开发7:Query查询

基于lucene的案例开发8:IndexSearcher中检索方法

基于lucene的案例开发9:案例初识

基于lucene的案例开发10:搜索后台基础,JsonUtil & XmlUtil类介绍

基于lucene的案例开发11:项目常用类ClassUtil & CharsetUtil介绍

基于lucene的案例开发12:数据库连接池

基于lucene的案例开发13:实现实时索引基本原理

基于lucene的案例开发14:实时索引管理类IndexManager

基于lucene的案例开发15:实时索引的检索

基于lucene的案例开发16:实时索引的修改

基于lucene的案例开发17:查询语句创建PackQuery

基于lucene的案例开发18:纵横小说更新列表页抓取

基于lucene的案例开发19:纵横小说简介页采集

基于lucene的案例开发20:纵横小说章节列表采集

基于lucene的案例开发21:纵横小说阅读页采集

资料来源:http://blog.csdn.net/xiaojimanman/article/details/44279753


欢迎加入about云群371358502、39327136,云计算爱好者群,亦可关注about云腾讯认证空间||关注本站微信

没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条