lucene 查询+分页+排序

lucene 查询+分页+排序

1、定义一个工厂类

LuceneFactory

复制代码
  1 import java.io.IOException;
  2 
  3 import org.apache.lucene.analysis.Analyzer;
  4 import org.apache.lucene.index.CorruptIndexException;
  5 import org.apache.lucene.index.IndexReader;
  6 import org.apache.lucene.index.IndexWriter;
  7 import org.apache.lucene.index.IndexWriterConfig;
  8 import org.apache.lucene.search.IndexSearcher;
  9 import org.apache.lucene.store.Directory;
 10 import org.apache.lucene.store.FSDirectory;
 11 import org.apache.lucene.util.Version;
 12 import org.wltea.analyzer.lucene.IKAnalyzer;
 13 
 14 import cn.utils.Constant;
 15 
 16 public class LuceneFactory
 17 {
 18     private static IndexReader fileReader = null;
 19     private static Directory fileDirectory = null;
 20     private static IndexWriter fileWriter = null;
 21     
 22     public static Analyzer ana = new IKAnalyzer();
 23     
 24     
 25     
 26     /**
 27      * 获取indexwriter
 28      * @return
 29      * @throws IOException
 30      */
 31     public static synchronized IndexWriter getFileWrite()  throws IOException 
 32     {
 33     
 34         if(fileWriter == null){
 35             fileDirectory = FSDirectory.open(Constant.file_index_path_File);
 36             if (IndexWriter.isLocked(fileDirectory)) {
 37                 IndexWriter.unlock(fileDirectory);
 38             }
 39             fileWriter = new IndexWriter(fileDirectory, new IndexWriterConfig(Version.LUCENE_36, ana));
 40             
 41             return fileWriter;
 42         }    
 43         
 44         System.out.println("filewriter != null");
 45         
 46         return fileWriter;
 47     }
 48     
 49     /**
 50      *获得IndexReader对象,判断是否为最新,不是则重新打开
 51      *@param file 索引路径的File对象
 52      **/
 53     public static synchronized IndexReader getFileRead() throws IOException 
 54     {
 55         if (fileReader == null) {
 56             fileDirectory = FSDirectory.open(Constant.file_index_path_File);
 57             fileReader = IndexReader.open(fileDirectory);
 58         } else {
 59             if (!fileReader.isCurrent()) {
 60                 fileReader = IndexReader.openIfChanged(fileReader);
 61             }
 62         }
 63         
 64         return fileReader;
 65     }
 66     
 67     /***
 68      * 获得IndexSearcher对象,判断当前的Searcher中reader是否为最新,如果不是,则重新创建IndexSearcher
 69      * 
 70      * @return
 71      * @throws IOException
 72      */
 73     public static synchronized IndexSearcher getFileSearch() throws IOException 
 74     {
 75         /*if (fileSearcher == null) {
 76             fileDirectory = FSDirectory.open(file_index_path);
 77             fileSearcher = new IndexSearcher(IndexReader.open(fileDirectory));
 78         } else {
 79             IndexReader r = fileSearcher.getIndexReader();
 80             if (!r.isCurrent()) {
 81                 fileSearcher.close();
 82                 fileSearcher = new IndexSearcher(IndexReader.openIfChanged(r));
 83             }
 84         }
 85         
 86         return fileSearcher;*/
 87         
 88         return new IndexSearcher(getFileRead());
 89     }
 90     
 91     public static void closeFileWrite()
 92     {
 93         if(fileWriter != null)
 94         {
 95             try
 96             {
 97                 fileWriter.commit();
 98                 fileWriter.close();
 99             } catch (CorruptIndexException e)
100             {
101                 
102                 e.printStackTrace();
103             } catch (IOException e)
104             {
105                 
106                 e.printStackTrace();
107             }
108             
109         }
110     }
111     
112 }


复制代码

2、定义返回结果bean

复制代码
 1 import java.util.List;
 2 
 3 import org.apache.lucene.document.Document;
 4 
 5 public class SearchResultBean
 6 {
 7     private int totalHits;
 8     private List<Document> docs;
 9 
10     public SearchResultBean()
11     {
12         
13     }
14 
15     public SearchResultBean(int totalHits, List<Document> docs)
16     {
17         this.totalHits = totalHits;
18         this.docs = docs;
19     }
20 
21     public int getTotalHits()
22     {
23         return this.totalHits;
24     }
25 
26     public void setTotalHits(int totalHits)
27     {
28         this.totalHits = totalHits;
29     }
30 
31     public List<Document> getDocs()
32     {
33         return this.docs;
34     }
35 
36     public void setDocs(List<Document> docs)
37     {
38         this.docs = docs;
39     }
40 }
复制代码

3、分页bean

复制代码
import java.util.ArrayList;
import java.util.List;

public class PageBean
{

    private int currentPage = 1;// 当前页数
    private int totalPages = 0;// 总页数
    private int pageSize = 0;// 每页显示数
    private int totalRows = 0;// 总数据数
    private int startNum = 0;// 开始记录
    private int nextPage = 0;// 下一页
    private int previousPage = 0;// 上一页
    private boolean hasNextPage = false;// 是否有下一页
    private boolean hasPreviousPage = false;// 是否有前一页
    private List<String> pageCodes;
    private int showPageSize = 8; //显示多少个超链接页面
    
    public PageBean() {}

    public PageBean(int pageSize, int currentPage, int totalRows)
    {

        this.pageSize = pageSize;
        this.currentPage = currentPage;
        this.totalRows = totalRows;

        if ((totalRows % pageSize) == 0)
        {
            totalPages = totalRows / pageSize;
        } else
        {
            totalPages = totalRows / pageSize + 1;
        }

        if (currentPage >= totalPages)
        {
            hasNextPage = false;
            currentPage = totalPages;
        } else
        {
            hasNextPage = true;
        }

        if (currentPage <= 1)
        {
            hasPreviousPage = false;
            currentPage = 1;
        } else
        {
            hasPreviousPage = true;
        }

        startNum = (currentPage - 1) * pageSize;
        nextPage = currentPage + 1;

        if (nextPage >= totalPages)
        {
            nextPage = totalPages;
        }

        previousPage = currentPage - 1;

        if (previousPage <= 1)
        {
            previousPage = 1;
        }

        reflashPageCode();
    }
    
    public void reflashPageCode()
    {
        this.pageCodes = new ArrayList<String>();
        if (this.totalPages <= this.showPageSize)
        {
            for (int i = 1; i <= this.totalPages; i++)
            {
                this.pageCodes.add(String.valueOf(i));
            }
            return;
        }
        int middleSide = this.showPageSize >> 1;
        if (this.currentPage <= middleSide)
        {
            for (int i = 1; i <= this.showPageSize; i++)
            {
                this.pageCodes.add(String.valueOf(i));
            }
            this.pageCodes.add(String.valueOf(".."));
            return;
        }
        if ((this.totalPages - this.currentPage) <= middleSide)
        {
            this.pageCodes.add(String.valueOf(".."));
            for (int i = this.showPageSize - 1; i >= 0; i--)
            {
                this.pageCodes.add(String.valueOf(this.totalPages - i));
            }
            return;
        }
        if (middleSide < this.currentPage
                && this.currentPage - (middleSide + 1) > 0)
            this.pageCodes.add(String.valueOf(".."));

        for (int i = 0; i < this.showPageSize; i++)
        {
            this.pageCodes.add(String.valueOf((this.currentPage + i)
                    - middleSide));
        }
        if (middleSide > this.currentPage
                || this.totalPages - (this.currentPage + middleSide) > 0)
            this.pageCodes.add(String.valueOf(".."));
    }

    public boolean isHasNextPage()
    {
        return hasNextPage;
    }

    public boolean isHasPreviousPage()
    {
        return hasPreviousPage;
    }

    /**
     * @return the nextPage
     */
    public int getNextPage()
    {
        return nextPage;
    }

    /**
     * @param nextPage
     *            the nextPage to set
     */
    public void setNextPage(int nextPage)
    {
        this.nextPage = nextPage;
    }

    /**
     * @return the previousPage
     */
    public int getPreviousPage()
    {
        return previousPage;
    }

    /**
     * @param previousPage
     *            the previousPage to set
     */
    public void setPreviousPage(int previousPage)
    {
        this.previousPage = previousPage;
    }

    /**
     * @return the currentPage
     */
    public int getCurrentPage()
    {
        return currentPage;
    }

    /**
     * @param currentPage
     *            the currentPage to set
     */
    public void setCurrentPage(int currentPage)
    {
        this.currentPage = currentPage;
    }

    /**
     * @return the pageSize
     */
    public int getPageSize()
    {
        return pageSize;
    }

    /**
     * @param pageSize
     *            the pageSize to set
     */
    public void setPageSize(int pageSize)
    {
        this.pageSize = pageSize;
    }

    /**
     * @return the totalPages
     */
    public int getTotalPages()
    {
        return totalPages;
    }

    /**
     * @param totalPages
     *            the totalPages to set
     */
    public void setTotalPages(int totalPages)
    {
        this.totalPages = totalPages;
    }

    /**
     * @return the totalRows
     */
    public int getTotalRows()
    {
        return totalRows;
    }

    /**
     * @param totalRows
     *            the totalRows to set
     */
    public void setTotalRows(int totalRows)
    {
        this.totalRows = totalRows;
    }

    /**
     * @param hasNextPage
     *            the hasNextPage to set
     */
    public void setHasNextPage(boolean hasNextPage)
    {
        this.hasNextPage = hasNextPage;
    }

    /**
     * @param hasPreviousPage
     *            the hasPreviousPage to set
     */
    public void setHasPreviousPage(boolean hasPreviousPage)
    {
        this.hasPreviousPage = hasPreviousPage;
    }

    /**
     * @return the startNum
     */
    public int getStartNum()
    {
        return startNum;
    }

    /**
     * @param startNum
     *            the startNum to set
     */
    public void setStartNum(int startNum)
    {
        this.startNum = startNum;
    }

    public List<String> getPageCodes()
    {
        if (this.pageCodes == null) {
              return new ArrayList<String>();
            }
        return pageCodes;
    }

    public void setPageCodes(List<String> pageCodes)
    {
        this.pageCodes = pageCodes;
    }

    public int getShowPageSize()
    {
        return showPageSize;
    }

    public void setShowPageSize(int showPageSize)
    {
        this.showPageSize = showPageSize;
    }
    
}
复制代码

4、搜索方法 重点

复制代码
 1 /****
 2      * 命名不是很好
 3      * @param field:暂时么用
 4      * @param query:query
 5      * @param first:分页起始值,如第一页0, first 0 max 20,第二页 first20, max 20
 6      * @param max:每页显示的数目,如20
 7      * @param sort:排序
 8      * @param highLight:是否高亮,这里不咱贴代码
 9      * @return
10      */
11     public static SearchResultBean searchAndSort(String field, Query query, int first,
12             int max, Sort sort, boolean highLight)
13     {
14         if(query == null){
15             System.out.println(" Query is null return null ");
16             return null;
17         }
18         try
19         {
20             List<Document> docs = new ArrayList<Document>();
21             IndexSearcher searcher = LuceneFactory.getFileSearch();
22 
23             TopFieldCollector c = TopFieldCollector.create(sort, first+max, false, false, false, false);
24             searcher.search(query, c);
25             ScoreDoc[] hits = c.topDocs(first, max).scoreDocs;
26             if (hits == null || hits.length < 1)
27                 return null;
28 
29             // 高亮------------------------------
30             Formatter htmlFormatter = null;
31             if (highLight)
32                 htmlFormatter = new SimpleHTMLFormatter(
33                         "<span style='color:red;'>", "</span>");
34             else
35                 htmlFormatter = new SimpleHTMLFormatter("", "");
36 
37             Scorer scorer = new QueryScorer(query);
38 //Encoder encoder = new SimpleHTMLEncoder(); 39 Fragmenter fragmenter = new SimpleFragmenter(Max_Match_Num); 40 Highlighter highlighter = new Highlighter(htmlFormatter, scorer); 41 highlighter.setTextFragmenter(fragmenter); 42 43 for (int i = 0; i < hits.length; i++) 44 { 45 Document doc = searcher.doc(hits[i].doc); 46 highlight(highlighter, doc, field); 47 48 docs.add(doc); 49 } 50 51 return new SearchResultBean(c.getTotalHits(), docs); 52 } catch (Exception e) 53 { 54 return null; 55 } 56 } 57
复制代码
  1.  第23行,max+first 值无所谓,返回的是命中数,不会是一个list集合,不用担心内存开销
  2.  第38行,中文分词、做高亮的时候,不注释这段代码,高亮的结果是unicode编码,搞不懂,暂时没研究。我用IK分词,测试与IK无关。
  3.  第51行,c.getTotalHits(),回到第一个问题,就是lucene分页,以前做数据库分页的时候,需要查询2次,而lucene只需要一次就OK。

分页jsp页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<script type="text/javascript" src="${pageContext.request.contextPath}/script/jquery.js"></script>
<div class="pagelistbox">
    <input type="hidden" name="currentPage" id="currentPage" value="${pager.currentPage}" />
    <span>共 ${pager.totalPages} 页/${pager.totalRows}条记录 </span>
    <c:if test="${pager.hasPreviousPage}">
        <span class="indexPage"> <a href="${pageContext.request.contextPath}/${page_url}1">首页</a></span>
    </c:if>
    <c:forEach var="every" items="${pager.pageCodes}">
        <c:choose>
            <c:when test="${every ne fn:trim(pager.currentPage) && every eq '..'}">
                <span>${every} </span>
            </c:when>
            <c:when test="${every ne fn:trim(pager.currentPage)}">
                <a href="${pageContext.request.contextPath}/${page_url}${every}">${every}</a>
            </c:when>
            <c:otherwise>
                <strong>${every}</strong>
            </c:otherwise>
        </c:choose>
    </c:forEach>
    <c:if test="${pager.hasNextPage}">
        <a class="nextPage" href="${pageContext.request.contextPath}/${page_url}${pager.nextPage}">下页</a>
        <a class="nextPage" href="${pageContext.request.contextPath}/${page_url}${pager.totalPages}">末页</a>
    </c:if>
</div>

  

 
 
 
标签: lucene分页排序
原文地址:https://www.cnblogs.com/Leo_wl/p/3181105.html