lucene搜寻结果分页显示 google、baidu式的分页

lucene搜索结果分页显示 google、baidu式的分页
1、jsp页面

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<style>
<!--
td{ font-size:12px; height:30px; line-height:30px;}
.serach_tab{padding:5px;}
.serach_tab td{}

.search_jieguo{ width:80%; margin-left:20px; margin-top:15px; margin-bottom:10px; }
.search_jieguo #tit{ font-size:14px; line-height:26px; height:26px;}
.search_jieguo #tit A:link {COLOR: #0048e6; TEXT-DECORATION: underline}
.search_jieguo #tit A:visited {COLOR: #ed0000; TEXT-DECORATION: underline}
.search_jieguo #tit A:hover {COLOR: #af0000; TEXT-DECORATION: underline}
.search_jieguo #tit A:active {COLOR: #ed0000; TEXT-DECORATION: underline}
.search_jieguo #neirong{ font-size:12px; line-height:20px; margin-left: 10px;}
.search_jieguo #link_xinxi{font-size: 12px;color: #488074; font-weight: bold; height:22px; line-height:22px;}
.search_jieguo #link_xinxi span{font-weight:normal; margin-right:30px; }

.page a{ margin-left: 5px; margin-right: 5px; font-size:14px;}
-->
</style>
<body style="margin:0px; padding:0px;">
<div style="width:1000px; margin:0 auto;">

</div>
<div>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
<script type="text/javascript" src="<c:url value='/js/jquery/jquery.js'/>"></script>
<script type="text/javascript" src="<c:url value='/js/jquery/plugin/jquery.form.js'/>"></script>
<script type="text/javascript" src="<c:url value='/js/jquery/plugin/jquery.validate.js'/>"></script>
<jsp:include page="/jsp/include/errorAndMsg.jsp"></jsp:include>
<html:form action="/html/searchindex.bc?method=searchCmsWebSiteIndex" styleId="cmsArticleForm" method="post" onsubmit="check()">
<table border="0" cellpadding="6" cellspacing="0" align="center" class="serach_tab">
<tr>
  <td align="right">搜索:</td>
  <td><html:text styleClass="form_1" styleId="title" property="searchkey"  style="width:300px;" maxlength="50"/></td>
  <td align="right">类别:</td>
  <td>
   <html:select property="field">
   <html:option value="title">标  题</html:option>
   <html:option value="subTitle">副标题 </html:option>
   <html:option value="key">关键字 </html:option>
   <html:option value="time">发布日期</html:option>
   <html:option value="author">作  者</html:option>
   <html:option value="from">来  源</html:option>
   <html:option value="content">内  容</html:option>
   </html:select>
  </td>
  <td align="right">站点:</td>
  <td>
   <html:select property="indexsiteid">
   <html:optionsCollection property="catalogTree" label="name" value="id"/>
   </html:select>
  </td>
  <td><html:submit value="提交" /></td>
</tr> 
</table>
</html:form>

<logic:present name="listdata">
  <div style="width:950px; margin-left: auto;margin-right: auto;">
<div style="border-top: 1px solid #6B90DA; background: #EBEFF9; height:28px; font-size:12px; font-weight: bold;text-indent: 5px;line-height: 28px; ">查询结果</div>  
  <logic:empty   name="listdata">  
           没有满足条件的结果
           </logic:empty>

    <logic:iterate id="element" indexId="ind" name="listdata" >
      <div class="search_jieguo">
     <div id="tit"><a href="http://${websiteurl}${element.link}">${element.title}</a></div>
     <div id="neirong"> ${element.content}</div>
     <div id="link_xinxi"><span>http://${websiteurl}${element.link}</span>${element.time}</div>
   </div>
    </logic:iterate></div></logic:present> 
<div style=" width:950px; margin: 0 auto; text-align:center; font-size:12px;  margin-top: 20px;padding-top:5px;border-bottom: 1px solid #6B90DA; background: #EBEFF9; height:28px; line-height:28px; margin-bottom: 10px;" class="page">
<%
int total =0;
if(request.getAttribute("total")!=null)
{
  String totalstr=request.getAttribute("total").toString();
    if(!totalstr.equals(""))
   total =Integer.parseInt(totalstr);//结果总数
}
int start = 0;//起始位置
if(request.getAttribute("start")!=null)
{
  String startstr=request.getAttribute("start").toString();
    if(!startstr.equals(""))
     start =Integer.parseInt(startstr);//结果总数
}
int rowsPerPage = 10;//设置一页显示的页码数目
int maxPage = ((total%rowsPerPage) == 0)?total/rowsPerPage:(total/rowsPerPage+1);//最大的页码
int curPage = start/rowsPerPage + 1;//当前页
if (curPage > 1 ) {
%>
<a href=javascript:to('<%=start-rowsPerPage%>')>上一页</a>
<%
}
if(maxPage > 10) {
int totalShow = curPage + 9;
int startPage = 0;
if(totalShow > maxPage) {
  totalShow = maxPage;
}
if(maxPage > 11 && curPage > 11) {
  startPage = curPage - 11;
}
for(int i=startPage;i<totalShow;i++) {
  if(i+1 == curPage) {
   %>&nbsp;[<%=i+1 %>]&nbsp;<%
  } else {
   %><a href=javascript:to('<%=i*rowsPerPage%>')>&nbsp;<%=i+1 %>&nbsp;</a><%
  }
}
} else {
for(int i=0;i<maxPage;i++) {
  if(i+1 == curPage) {
   %>&nbsp;[<%=i+1 %>]&nbsp;<%
  } else {
   %><a href=javascript:to('<%=i*rowsPerPage%>')>&nbsp;<%=i+1 %>&nbsp;</a><%
  }
}
}
if (curPage < maxPage) {
%>
  <a href=javascript:to('<%=curPage*rowsPerPage%>')>下一页</a>
<%}
%>
<script type="text/javascript">
function  to(t)
{
   var startNo =t;
   cmsArticleForm.action="<c:url value='/html/searchindex.bc?method=searchCmsWebSiteIndex&start='/>"+startNo;
cmsArticleForm.submit();
}

function check()
{

   if(cmsArticleForm.searchkey==null||cmsArticleForm.searchkey=="")
   alert(999);
}
</script>
</div>
</div>
<div style="width:1000px; margin:0 auto; position:absolute; bottom:0px;">

</div>
</body>
</html>

2、action

public ActionForward searchCmsWebSiteIndex(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
{
  log.info("create index of the websites");
  String indexsiteid = request.getParameter("indexsiteid");
  int nstart = 0;
  int total = 0;
  String start = request.getParameter("start");
  if (start != null && !start.equals(""))
   nstart = Integer.parseInt(start.trim());
  String field = request.getParameter("field");
  String searchkey = request.getParameter("searchkey");
  ICmsCatalogBO catalogService = (ICmsCatalogBO) getService(ConstantDefine.SERVICE_CMS_CATALOG);
  TCmsCatalog catalog = (TCmsCatalog) catalogService.get(TCmsCatalog.class,
   indexsiteid);
  String websiteurl = catalog.getWebsiteUrl();
  String siteName = catalog.getCode();
  String locationIndex = XmlConfigurationHelper.getPath("index-dir");
  String indexPath = locationIndex + "\\" + siteName + "\\";
  SearchFiles searchfile = new SearchFiles();
  List<HashMap<String, String>> listdata = searchfile.searchIndex(
   indexPath, field, searchkey, nstart);
  total = searchfile.getHitsTotal();
  request.setAttribute("start", nstart);
  request.setAttribute("total", total);
  request.setAttribute("websiteurl", websiteurl);
  request.setAttribute("listdata", listdata);
  List<TCmsCatalog> topCatalogList = catalogService.findTopCatalog();
  CmsArticleForm articleForm = (CmsArticleForm) form;
  articleForm.setCatalogTree(topCatalogList);
  return mapping.findForward(ConstantDefine.FORWARD_QUERY);
}

3、主要的搜索类


package com.berheley.components.lucene;

/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.cn.ChineseAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.FilterIndexReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Searcher;

/** Simple command-line based search demo. */
public class SearchFiles
{

private int hitsTotal;

/**
  * Use the norms from one field for all fields. Norms are read into memory, using a byte of
  * memory per document per searched field. This can cause search of large collections with a
  * large number of fields to run out of memory. If all of the fields contain only a single token,
  * then the norms are all identical, then single norm vector may be shared.
  */
private static class OneNormsReader extends FilterIndexReader
{

  private final String field;

  public OneNormsReader(IndexReader in, String field)
  {
   super(in);
   this.field = field;
  }

  @Override
  public byte[] norms(String field) throws IOException
  {
   return in.norms(this.field);
  }
}

public SearchFiles()
{
}

public List<HashMap<String, String>> searchIndex(String indexPath, String field, String searchkey, int nstart)
{
  List<HashMap<String, String>> docList = new ArrayList<HashMap<String, String>>();
  String indexpath = indexPath;
  // indexpath = "D:\\webapps\\cms\\indexes\\tjtggov";
  String normsField = null;
  IndexReader reader;
  try
  {
   reader = IndexReader.open(indexpath);
   if (normsField != null)
    reader = new OneNormsReader(reader, normsField);
   Searcher searcher = new IndexSearcher(reader);
   Analyzer analyzer = new ChineseAnalyzer();
   QueryParser parser = new QueryParser(field, analyzer);
   if (searchkey != null)
    searchkey = searchkey.trim();
   try
   {
    Query query;
    query = parser.parse(searchkey);
    System.out.println("Searching for: " + query.toString(searchkey));
    Date start = new Date();
    Hits hits = searcher.search(query);
    Date end = new Date();
    System.out.println("Time: "
       + (end.getTime() - start.getTime())
       + "ms");
    System.out.println(hits.length() + " total matching documents");
    setHitsTotal(hits.length());
    // 如果最后一页数量小于每页显示的数量则全部显示
    // int length = hits.length();
    final int HITS_PER_PAGE = 10;
    // for (int start_ = 0; start_ < hits.length(); start_ += HITS_PER_PAGE)
    // {
    int end_ = Math.min(hits.length(), nstart + HITS_PER_PAGE);
    for (int i = nstart; i < end_; i++)
    {
     Document doc = hits.doc(i);
     String path = doc.get("path");
     final HashMap<String, String> dataMap = new HashMap<String, String>();
     dataMap.put("path", doc.get("path"));
     dataMap.put("title", doc.get("title"));
     dataMap.put("link", doc.get("link"));
     if (doc.get("content").length() > 200)
      dataMap.put("content", doc.get("content").substring(0, 200));
     else
      dataMap.put("content", doc.get("content"));
     dataMap.put("time", doc.get("time"));
     dataMap.put("subTitle", doc.get("subTitle"));
     dataMap.put("key", doc.get("key"));
     dataMap.put("author", doc.get("author"));
     dataMap.put("from", doc.get("from"));
     docList.add(dataMap);
     if (path != null)
     {
      System.out.println((i + 1) + ". " + path);
      String title = doc.get("title");
      if (title != null)
      {
       System.out.println("   Title: " + doc.get("title"));
      }
     } else
     {
      System.out.println((i + 1)
         + ". "
         + "No path for this document");
     }
    }
    // }
    reader.close();
   } catch (ParseException e)
   {
    e.printStackTrace();
   }
  } catch (CorruptIndexException e)
  {
   e.printStackTrace();
  } catch (IOException e)
  {
   e.printStackTrace();
  }
  return docList;
}

public int getHitsTotal()
{
  return hitsTotal;
}

public void setHitsTotal(int hitsTotal)
{
  this.hitsTotal = hitsTotal;
}
}