zoukankan      html  css  js  c++  java
  • 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分页排序
  • 相关阅读:
    LVS 模式
    修改RocketMQ的NameServer端口
    一次清理Hbase的oldWALs的过程
    Linux下删除文件系统空间不释放的问题
    HBase 强制删除表
    关闭Found duplicated code
    Java操作HDFS代码样例
    RocketMQ:Cannot allocate memory
    Storm的StreamID使用样例(版本1.0.2)
    android studio 编译sdk版降低报错解决方法
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3181105.html
Copyright © 2011-2022 走看看