Lucene5学习之LuceneUtils工具类简单封装

花了整整一天时间,将Lucene5中有关索引的常见操作进行了简单封装,废话不多说,上代码:

package com.yida.framework.lucene5.util;

import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.LockObtainFailedException;
/**
 * Lucene索引读写器/查询器单例获取工具类
 * @author Lanxiaowei
 *
 */
public class LuceneManager {
  private volatile static LuceneManager singleton;

  private volatile static IndexWriter writer;

  private volatile static IndexReader reader;

  private volatile static IndexSearcher searcher;

  private final Lock writerLock = new ReentrantLock();

  //private final Lock readerLock = new ReentrantLock();

  //private final Lock searcherLock = new ReentrantLock();

  private LuceneManager() {}

  public static LuceneManager getInstance() {
    if (null == singleton) {
      synchronized (LuceneManager.class) {
        if (null == singleton) {
          singleton = new LuceneManager();
        }
      }
    }
    return singleton;
  }

  /**
   * 获取IndexWriter单例对象
   * @param dir
   * @param config
   * @return
   */
  public IndexWriter getIndexWriter(Directory dir, IndexWriterConfig config) {
    if(null == dir) {
      throw new IllegalArgumentException("Directory can not be null.");
    }
    if(null == config) {
      throw new IllegalArgumentException("IndexWriterConfig can not be null.");
    }
    try {
      writerLock.lock();
      if(null == writer){
        //如果索引目录被锁,则直接抛异常
        if(IndexWriter.isLocked(dir)) {
          throw new LockObtainFailedException("Directory of index had been locked.");
        }
        writer = new IndexWriter(dir, config);
      }
    } catch (LockObtainFailedException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      writerLock.unlock();
    }
    return writer;
  }

  /**
   * 获取IndexReader对象
   * @param dir
   * @param enableNRTReader  是否开启NRTReader
   * @return
   */
  public IndexReader getIndexReader(Directory dir,boolean enableNRTReader) {
    if(null == dir) {
      throw new IllegalArgumentException("Directory can not be null.");
    }
    try {
      if(null == reader){
        reader = DirectoryReader.open(dir);
      } else {
        if(enableNRTReader && reader instanceof DirectoryReader) {
          //开启近实时Reader,能立即看到动态添加/删除的索引变化
          reader = DirectoryReader.openIfChanged((DirectoryReader)reader);
        }
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
    return reader;
  }

  /**
   * 获取IndexReader对象(默认不启用NETReader)
   * @param dir
   * @return
   */
  public IndexReader getIndexReader(Directory dir) {
    return getIndexReader(dir, false);
  }

  /**
   * 获取IndexSearcher对象
   * @param reader    IndexReader对象实例
   * @param executor  如果你需要开启多线程查询,请提供ExecutorService对象参数
   * @return
   */
  public IndexSearcher getIndexSearcher(IndexReader reader,ExecutorService executor) {
    if(null == reader) {
      throw new IllegalArgumentException("The indexReader can not be null.");
    }
    if(null == searcher){
      searcher = new IndexSearcher(reader);
    }
    return searcher;
  }

  /**
   * 获取IndexSearcher对象(不支持多线程查询)
   * @param reader    IndexReader对象实例
   * @return
   */
  public IndexSearcher getIndexSearcher(IndexReader reader) {
    return getIndexSearcher(reader, null);
  }
}
package com.yida.framework.lucene5.util;

import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;

import org.ansj.lucene5.AnsjAnalyzer;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Formatter;
import org.apache.lucene.search.highlight.Fragmenter;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.Scorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

/**
 * Lucene工具类(基于Lucene5.0封装)
 * @author Lanxiaowei
 *
 */
public class LuceneUtils {
  private static final LuceneManager luceneManager = LuceneManager.getInstance();
  private static Analyzer analyzer = new AnsjAnalyzer();

  /**
   * 打开索引目录
   *
   * @param luceneDir
   * @return
   * @throws IOException
   */
  public static FSDirectory openFSDirectory(String luceneDir) {
    FSDirectory directory = null;
    try {
      directory = FSDirectory.open(Paths.get(luceneDir));
      /**
       * 注意:isLocked方法内部会试图去获取Lock,如果获取到Lock,会关闭它,否则return false表示索引目录没有被锁,
       * 这也就是为什么unlock方法被从IndexWriter类中移除的原因
       */
      IndexWriter.isLocked(directory);
    } catch (IOException e) {
      e.printStackTrace();
    }
    return directory;
  }

  /**
   * 关闭索引目录并销毁
   * @param directory
   * @throws IOException
   */
  public static void closeDirectory(Directory directory) throws IOException {
    if (null != directory) {
      directory.close();
      directory = null;
    }
  }

  /**
   * 获取IndexWriter
   * @param dir
   * @param config
   * @return
   */
  public static IndexWriter getIndexWrtier(Directory dir, IndexWriterConfig config) {
    return luceneManager.getIndexWriter(dir, config);
  }

  /**
   * 获取IndexWriter
   * @param dir
   * @param config
   * @return
   */
  public static IndexWriter getIndexWrtier(String directoryPath, IndexWriterConfig config) {
    FSDirectory directory = openFSDirectory(directoryPath);
    return luceneManager.getIndexWriter(directory, config);
  }

  /**
   * 获取IndexReader
   * @param dir
   * @param enableNRTReader  是否开启NRTReader
   * @return
   */
  public static IndexReader getIndexReader(Directory dir,boolean enableNRTReader) {
    return luceneManager.getIndexReader(dir, enableNRTReader);
  }

  /**
   * 获取IndexReader(默认不启用NRTReader)
   * @param dir
   * @return
   */
  public static IndexReader getIndexReader(Directory dir) {
    return luceneManager.getIndexReader(dir);
  }

  /**
   * 获取IndexSearcher
   * @param reader    IndexReader对象
   * @param executor  如果你需要开启多线程查询,请提供ExecutorService对象参数
   * @return
   */
  public static IndexSearcher getIndexSearcher(IndexReader reader,ExecutorService executor) {
    return luceneManager.getIndexSearcher(reader, executor);
  }

  /**
   * 获取IndexSearcher(不支持多线程查询)
   * @param reader    IndexReader对象
   * @return
   */
  public static IndexSearcher getIndexSearcher(IndexReader reader) {
    return luceneManager.getIndexSearcher(reader);
  }

  /**
   * 创建QueryParser对象
   * @param field
   * @param analyzer
   * @return
   */
  public static QueryParser createQueryParser(String field, Analyzer analyzer) {
    return new QueryParser(field, analyzer);
  }

  /**
   * 关闭IndexReader
   * @param reader
   */
  public static void closeIndexReader(IndexReader reader) {
    if (null != reader) {
      try {
        reader.close();
        reader = null;
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

  /**
   * 关闭IndexWriter
   * @param writer
   */
  public static void closeIndexWriter(IndexWriter writer) {
    if(null != writer) {
      try {
        writer.close();
        writer = null;
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

  /**
   * 关闭IndexReader和IndexWriter
   * @param reader
   * @param writer
   */
  public static void closeAll(IndexReader reader, IndexWriter writer) {
    closeIndexReader(reader);
    closeIndexWriter(writer);
  }

  /**
   * 删除索引[注意:请自己关闭IndexWriter对象]
   * @param writer
   * @param field
   * @param value
   */
  public static void deleteIndex(IndexWriter writer, String field, String value) {
    try {
      writer.deleteDocuments(new Term[] {new Term(field,value)});
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  /**
   * 删除索引[注意:请自己关闭IndexWriter对象]
   * @param writer
   * @param query
   */
  public static void deleteIndex(IndexWriter writer, Query query) {
    try {
      writer.deleteDocuments(query);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  /**
   * 批量删除索引[注意:请自己关闭IndexWriter对象]
   * @param writer
   * @param terms
   */
  public static void deleteIndexs(IndexWriter writer,Term[] terms) {
    try {
      writer.deleteDocuments(terms);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  /**
   * 批量删除索引[注意:请自己关闭IndexWriter对象]
   * @param writer
   * @param querys
   */
  public static void deleteIndexs(IndexWriter writer,Query[] querys) {
    try {
      writer.deleteDocuments(querys);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  /**
   * 删除所有索引文档
   * @param writer
   */
  public static void deleteAllIndex(IndexWriter writer) {
    try {
      writer.deleteAll();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  /**
   * 更新索引文档
   * @param writer
   * @param term
   * @param document
   */
  public static void updateIndex(IndexWriter writer,Term term,Document document) {
    try {
      writer.updateDocument(term, document);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  /**
   * 更新索引文档
   * @param writer
   * @param term
   * @param document
   */
  public static void updateIndex(IndexWriter writer,String field,String value,Document document) {
    updateIndex(writer, new Term(field, value), document);
  }

  /**
   * 添加索引文档
   * @param writer
   * @param doc
   */
  public static void addIndex(IndexWriter writer, Document document) {
    updateIndex(writer, null, document);
  }

  /**
   * 索引文档查询
   * @param searcher
   * @param query
   * @return
   */
  public static List<Document> query(IndexSearcher searcher,Query query) {
    TopDocs topDocs = null;
    try {
      topDocs = searcher.search(query, Integer.MAX_VALUE);
    } catch (IOException e) {
      e.printStackTrace();
    }
    ScoreDoc[] scores = topDocs.scoreDocs;
    int length = scores.length;
    if (length <= 0) {
      return Collections.emptyList();
    }
    List<Document> docList = new ArrayList<Document>();
    try {
      for (int i = 0; i < length; i++) {
        Document doc = searcher.doc(scores[i].doc);
        docList.add(doc);
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
    return docList;
  }

  /**
   * 返回索引文档的总数[注意:请自己手动关闭IndexReader]
   * @param reader
   * @return
   */
  public static int getIndexTotalCount(IndexReader reader) {
    return reader.numDocs();
  }

  /**
   * 返回索引文档中最大文档ID[注意:请自己手动关闭IndexReader]
   * @param reader
   * @return
   */
  public static int getMaxDocId(IndexReader reader) {
    return reader.maxDoc();
  }

  /**
   * 返回已经删除尚未提交的文档总数[注意:请自己手动关闭IndexReader]
   * @param reader
   * @return
   */
  public static int getDeletedDocNum(IndexReader reader) {
    return getMaxDocId(reader) - getIndexTotalCount(reader);
  }

  /**
   * 根据docId查询索引文档
   * @param reader         IndexReader对象
   * @param docID          documentId
   * @param fieldsToLoad   需要返回的field
   * @return
   */
  public static Document findDocumentByDocId(IndexReader reader,int docID, Set<String> fieldsToLoad) {
    try {
      return reader.document(docID, fieldsToLoad);
    } catch (IOException e) {
      return null;
    }
  }

  /**
   * 根据docId查询索引文档
   * @param reader         IndexReader对象
   * @param docID          documentId
   * @return
   */
  public static Document findDocumentByDocId(IndexReader reader,int docID) {
    return findDocumentByDocId(reader, docID, null);
  }

  /**
   * @Title: createHighlighter
   * @Description: 创建高亮器
   * @param query             索引查询对象
   * @param prefix            高亮前缀字符串
   * @param stuffix           高亮后缀字符串
   * @param fragmenterLength  摘要最大长度
   * @return
   */
  public static Highlighter createHighlighter(Query query, String prefix, String stuffix, int fragmenterLength) {
    Formatter formatter = new SimpleHTMLFormatter((prefix == null || prefix.trim().length() == 0) ?
      "<font color=\"red\">" : prefix, (stuffix == null || stuffix.trim().length() == 0)?"</font>" : stuffix);
    Scorer fragmentScorer = new QueryScorer(query);
    Highlighter highlighter = new Highlighter(formatter, fragmentScorer);
    Fragmenter fragmenter = new SimpleFragmenter(fragmenterLength <= 0 ? 50 : fragmenterLength);
    highlighter.setTextFragmenter(fragmenter);
    return highlighter;
  }

  /**
   * @Title: highlight
   * @Description: 生成高亮文本
   * @param document          索引文档对象
   * @param highlighter       高亮器
   * @param analyzer          索引分词器
   * @param field             高亮字段
   * @return
   * @throws IOException
   * @throws InvalidTokenOffsetsException
   */
  public static String highlight(Document document,Highlighter highlighter,Analyzer analyzer,String field) throws IOException {
    List<IndexableField> list = document.getFields();
    for (IndexableField fieldable : list) {
      String fieldValue = fieldable.stringValue();
      if(fieldable.name().equals(field)) {
        try {
          fieldValue = highlighter.getBestFragment(analyzer, field, fieldValue);
        } catch (InvalidTokenOffsetsException e) {
          fieldValue = fieldable.stringValue();
        }
        return (fieldValue == null || fieldValue.trim().length() == 0)? fieldable.stringValue() : fieldValue;
      }
    }
    return null;
  }

  /**
   * @Title: searchTotalRecord
   * @Description: 获取符合条件的总记录数
   * @param query
   * @return
   * @throws IOException
   */
  public static int searchTotalRecord(IndexSearcher search,Query query) {
    ScoreDoc[] docs = null;
    try {
      TopDocs topDocs = search.search(query, Integer.MAX_VALUE);
      if(topDocs == null || topDocs.scoreDocs == null || topDocs.scoreDocs.length == 0) {
        return 0;
      }
      docs = topDocs.scoreDocs;
    } catch (IOException e) {
      e.printStackTrace();
    }
    return docs.length;
  }

  /**
   * @Title: pageQuery
   * @Description: Lucene分页查询
   * @param searcher
   * @param query
   * @param page
   * @throws IOException
   */
  public static void pageQuery(IndexSearcher searcher,Directory directory,Query query,Page<Document> page) {
    int totalRecord = searchTotalRecord(searcher,query);
    //设置总记录数
    page.setTotalRecord(totalRecord);
    TopDocs topDocs = null;
    try {
      topDocs = searcher.searchAfter(page.getAfterDoc(),query, page.getPageSize());
    } catch (IOException e) {
      e.printStackTrace();
    }
    List<Document> docList = new ArrayList<Document>();
    ScoreDoc[] docs = topDocs.scoreDocs;
    int index = 0;
    for (ScoreDoc scoreDoc : docs) {
      int docID = scoreDoc.doc;
      Document document = null;
      try {
        document = searcher.doc(docID);
      } catch (IOException e) {
        e.printStackTrace();
      }
      if(index == docs.length - 1) {
        page.setAfterDoc(scoreDoc);
        page.setAfterDocId(docID);
      }
      docList.add(document);
      index++;
    }
    page.setItems(docList);
    closeIndexReader(searcher.getIndexReader());
  }

  /**
   * @Title: pageQuery
   * @Description: 分页查询[如果设置了高亮,则会更新索引文档]
   * @param searcher
   * @param directory
   * @param query
   * @param page
   * @param highlighterParam
   * @param writerConfig
   * @throws IOException
   */
  public static void pageQuery(IndexSearcher searcher,Directory directory,Query query,Page<Document> page,HighlighterParam highlighterParam,IndexWriterConfig writerConfig) throws IOException {
    IndexWriter writer = null;
    //若未设置高亮
    if(null == highlighterParam || !highlighterParam.isHighlight()) {
      pageQuery(searcher,directory,query, page);
    } else {
      int totalRecord = searchTotalRecord(searcher,query);
      System.out.println("totalRecord:" + totalRecord);
      //设置总记录数
      page.setTotalRecord(totalRecord);
      TopDocs topDocs = searcher.searchAfter(page.getAfterDoc(),query, page.getPageSize());
      List<Document> docList = new ArrayList<Document>();
      ScoreDoc[] docs = topDocs.scoreDocs;
      int index = 0;
      writer = getIndexWrtier(directory, writerConfig);
      for (ScoreDoc scoreDoc : docs) {
        int docID = scoreDoc.doc;
        Document document = searcher.doc(docID);
        String content = document.get(highlighterParam.getFieldName());
        if(null != content && content.trim().length() > 0) {
          //创建高亮器
          Highlighter highlighter = LuceneUtils.createHighlighter(query,
            highlighterParam.getPrefix(), highlighterParam.getStuffix(),
            highlighterParam.getFragmenterLength());
          String text = highlight(document, highlighter, analyzer, highlighterParam.getFieldName());
          //若高亮后跟原始文本不相同,表示高亮成功
          if(!text.equals(content)) {
            Document tempdocument = new Document();
            List<IndexableField> indexableFieldList = document.getFields();
            if(null != indexableFieldList && indexableFieldList.size() > 0) {
              for(IndexableField field : indexableFieldList) {
                if(field.name().equals(highlighterParam.getFieldName())) {
                  tempdocument.add(new TextField(field.name(), text, Field.Store.YES));
                } else {
                  tempdocument.add(field);
                }
              }
            }
            updateIndex(writer, new Term(highlighterParam.getFieldName(),content), tempdocument);
            document = tempdocument;
          }
        }
        if(index == docs.length - 1) {
          page.setAfterDoc(scoreDoc);
          page.setAfterDocId(docID);
        }
        docList.add(document);
        index++;
      }
      page.setItems(docList);
    }
    closeIndexReader(searcher.getIndexReader());
    closeIndexWriter(writer);
  }
}
package com.yida.framework.lucene5.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.lucene.document.Document;
import org.apache.lucene.search.ScoreDoc;
public class Page<T> {
  /**当前第几页(从1开始计算)*/
  private int currentPage;
  /**每页显示几条*/
  private int pageSize;
  /**总记录数*/
  private int totalRecord;
  /**总页数*/
  private int totalPage;
  /**分页数据集合[用泛型T来限定集合元素类型]*/
  private Collection<T> items;
  /**当前显示起始索引(从零开始计算)*/
  private int startIndex;
  /**当前显示结束索引(从零开始计算)*/
  private int endIndex;
  /**一组最多显示几个页码[比如Google一组最多显示10个页码]*/
  private int groupSize;
  /**左边偏移量*/
  private int leftOffset = 5;
  /**右边偏移量*/
  private int rightOffset = 4;
  /**当前页码范围*/
  private String[] pageRange;
  /**分页数据*/
  private List<Document> docList;
  /**上一页最后一个ScoreDoc对象*/
  private ScoreDoc afterDoc;
  /**上一页最后一个ScoreDoc对象的Document对象ID*/
  private int afterDocId;
  public void setRangeIndex() {
    int groupSize = getGroupSize();
    int totalPage = getTotalPage();
    if(totalPage < 2) {
      startIndex = 0;
      endIndex = totalPage - startIndex;
    } else {
      int currentPage = getCurrentPage();
      if(groupSize >= totalPage) {
        startIndex = 0;
        endIndex = totalPage - startIndex - 1;
      } else {
        int leftOffset = getLeftOffset();
        int middleOffset = getMiddleOffset();
        if(-1 == middleOffset) {
          startIndex = 0;
          endIndex = groupSize - 1;
        } else if(currentPage <= leftOffset) {
          startIndex = 0;
          endIndex = groupSize - 1;
        } else {
          startIndex = currentPage - leftOffset - 1;
          if(currentPage + rightOffset > totalPage) {
            endIndex = totalPage - 1;
          } else {
            endIndex = currentPage + rightOffset - 1;
          }
        }
      }
    }
  }
  public int getCurrentPage() {
    if(currentPage <= 0) {
      currentPage = 1;
    } else {
      int totalPage = getTotalPage();
      if(totalPage > 0 && currentPage > getTotalPage()) {
        currentPage = totalPage;
      }
    }
    return currentPage;
  }
  public void setCurrentPage(int currentPage) {
    this.currentPage = currentPage;
  }
  public int getPageSize() {
    if(pageSize <= 0) {
      pageSize = 10;
    }
    return pageSize;
  }
  public void setPageSize(int pageSize) {
    this.pageSize = pageSize;
  }
  public int getTotalRecord() {
    return totalRecord;
  }
  public void setTotalRecord(int totalRecord) {
    this.totalRecord = totalRecord;
  }
  public int getTotalPage() {
    int totalRecord = getTotalRecord();
    if(totalRecord == 0) {
      totalPage = 0;
    } else {
      int pageSize = getPageSize();
      totalPage = totalRecord % pageSize == 0 ? totalRecord / pageSize : (totalRecord / pageSize) + 1;
    }
    return totalPage;
  }
  public void setTotalPage(int totalPage) {
    this.totalPage = totalPage;
  }
  public int getStartIndex() {
    return startIndex;
  }
  public void setStartIndex(int startIndex) {
    this.startIndex = startIndex;
  }
  public int getEndIndex() {
    return endIndex;
  }
  public void setEndIndex(int endIndex) {
    this.endIndex = endIndex;
  }
  public int getGroupSize() {
    if(groupSize <= 0) {
      groupSize = 10;
    }
    return groupSize;
  }
  public void setGroupSize(int groupSize) {
    this.groupSize = groupSize;
  }
  public int getLeftOffset() {
    leftOffset = getGroupSize() / 2;
    return leftOffset;
  }
  public void setLeftOffset(int leftOffset) {
    this.leftOffset = leftOffset;
  }
  public int getRightOffset() {
    int groupSize = getGroupSize();
    if(groupSize % 2 == 0) {
      rightOffset = (groupSize / 2) - 1;
    } else {
      rightOffset = groupSize / 2;
    }
    return rightOffset;
  }
  public void setRightOffset(int rightOffset) {
    this.rightOffset = rightOffset;
  }
  /**中心位置索引[从1开始计算]*/
  public int getMiddleOffset() {
    int groupSize = getGroupSize();
    int totalPage = getTotalPage();
    if(groupSize >= totalPage) {
      return -1;
    }
    return getLeftOffset() + 1;
  }
  public String[] getPageRange() {
    setRangeIndex();
    int size = endIndex - startIndex + 1;
    if(size <= 0) {
      return new String[0];
    }
    if(totalPage == 1) {
      return new String[] {"1"};
    }
    pageRange = new String[size];
    for(int i=0; i < size; i++) {
      pageRange[i] = (startIndex + i + 1) + "";
    }
    return pageRange;
  }
  public void setPageRange(String[] pageRange) {
    this.pageRange = pageRange;
  }
  public Collection<T> getItems() {
    return items;
  }
  public void setItems(Collection<T> items) {
    this.items = items;
  }
  public List<Document> getDocList() {
    return docList;
  }
  public void setDocList(List<Document> docList) {
    this.docList = docList;
  }
  public ScoreDoc getAfterDoc() {
    setAfterDocId(afterDocId);
    return afterDoc;
  }
  public void setAfterDoc(ScoreDoc afterDoc) {
    this.afterDoc = afterDoc;
  }
  public int getAfterDocId() {
    return afterDocId;
  }
  public void setAfterDocId(int afterDocId) {
    this.afterDocId = afterDocId;
    if(null == afterDoc) {
      this.afterDoc = new ScoreDoc(afterDocId, 1.0f);
    }
  }
  public Page() {}
  public Page(int currentPage, int pageSize) {
    this.currentPage = currentPage;
    this.pageSize = pageSize;
  }
  public Page(int currentPage, int pageSize, Collection<T> items) {
    this.currentPage = currentPage;
    this.pageSize = pageSize;
    this.items = items;
  }
  public Page(int currentPage, int pageSize, Collection<T> items, int groupSize) {
    this.currentPage = currentPage;
    this.pageSize = pageSize;
    this.items = items;
    this.groupSize = groupSize;
  }
  public Page(int currentPage, int pageSize, int groupSize, int afterDocId) {
    this.currentPage = currentPage;
    this.pageSize = pageSize;
    this.groupSize = groupSize;
    this.afterDocId = afterDocId;
  }
  public static void main(String[] args) {
    Collection<Integer> items = new ArrayList<Integer>();
    int totalRecord = 201;
    for(int i=0; i < totalRecord; i++) {
      items.add(new Integer(i));
    }
    Page<Integer> page = new Page<Integer>(1,10,items,10);
    page.setTotalRecord(totalRecord);
    int totalPage = page.getTotalPage();
    for(int i=0; i < totalPage; i++) {
      page.setCurrentPage(i+1);
      String[] pageRange = page.getPageRange();
      System.out.println("当前第" + page.currentPage + "页");
      for(int j=0; j < pageRange.length; j++) {
        System.out.print(pageRange[j] + "  ");
      }
      System.out.println("\n");
    }
  }
}
package com.yida.framework.lucene5.util;
/**
 * @ClassName: HighlighterParam
 * @Description: 高亮器参数对象
 * @author Lanxiaowei
 * @date 2014-3-30 下午12:22:08
 */
public class HighlighterParam {
  /**是否需要设置高亮*/
  private boolean highlight;
  /**需要设置高亮的属性名*/
  private String fieldName;
  /**高亮前缀*/
  private String prefix;
  /**高亮后缀*/
  private String stuffix;
  /**显示摘要最大长度*/
  private int fragmenterLength;
  public boolean isHighlight() {
    return highlight;
  }
  public void setHighlight(boolean highlight) {
    this.highlight = highlight;
  }
  public String getFieldName() {
    return fieldName;
  }
  public void setFieldName(String fieldName) {
    this.fieldName = fieldName;
  }
  public String getPrefix() {
    return prefix;
  }
  public void setPrefix(String prefix) {
    this.prefix = prefix;
  }
  public String getStuffix() {
    return stuffix;
  }
  public void setStuffix(String stuffix) {
    this.stuffix = stuffix;
  }
  public int getFragmenterLength() {
    return fragmenterLength;
  }
  public void setFragmenterLength(int fragmenterLength) {
    this.fragmenterLength = fragmenterLength;
  }
  public HighlighterParam(boolean highlight, String fieldName, String prefix, String stuffix, int fragmenterLength) {
    this.highlight = highlight;
    this.fieldName = fieldName;
    this.prefix = prefix;
    this.stuffix = stuffix;
    this.fragmenterLength = fragmenterLength;
  }

  public HighlighterParam(boolean highlight, String fieldName, int fragmenterLength) {
    this.highlight = highlight;
    this.fieldName = fieldName;
    this.fragmenterLength = fragmenterLength;
  }

  public HighlighterParam(boolean highlight, String fieldName, String prefix, String stuffix) {
    this.highlight = highlight;
    this.fieldName = fieldName;
    this.prefix = prefix;
    this.stuffix = stuffix;
  }
  public HighlighterParam() {
  }
}

工具类对IndexWriter,IndexReader,IndexSearcher,Analyzer,QueryParser等Lucene这些常用操作对象的获取进行了封装,其中IndexWriter采用了单例模式,确保始终只有一个对象实例,因为Lucene限制了索引写操作是阻塞的,即同一时刻只能有一个IndexWriter在执行写操作,直到indexWriter释放lock,而索引读的操作是可以并发进行的。

时间: 2024-10-08 12:49:50

Lucene5学习之LuceneUtils工具类简单封装的相关文章

iOS开发--QQ音乐练习,旋转动画的实现,音乐工具类的封装,定时器的使用技巧,SliderBar的事件处理

一.旋转动画的实现 二.音乐工具类的封装 -- 返回所有歌曲,返回当前播放歌曲,设置当前播放歌曲,返回下一首歌曲,返回上一首歌曲方法的实现 头文件 .m文件 1 #import "ChaosMusicTool.h" 2 #import "MJExtension.h" 3 #import "ChaosMusic.h" 4 5 static NSArray *_musics; 6 static ChaosMusic *_playingMusic; 7

Java学习-049-正则工具类

自去年九月份决定再次入学和职业资格进阶,开始备战二者考试至今,以及当下进行中的职称申请,犹如孤独的狼,不断前行在路上,而今凡凡总总的已历8月... 不感慨了,如下为一园友需要的正则工具类,直接上码: 1 public class RegUtils { 2 private static Logger logger = Logger.getLogger(RegUtils.class.getName()); 3 private static String msg = ""; 4 privat

javascript 总结(常用工具类的封装,转)

javascript 总结(常用工具类的封装) 前言 因为工作中经常用到这些方法,所有便把这些方法进行了总结. JavaScript 1. type 类型判断 isString (o) { //是否字符串 return Object.prototype.toString.call(o).slice(8, -1) === 'String' } isNumber (o) { //是否数字 return Object.prototype.toString.call(o).slice(8, -1) ==

观察者模式学习--使用jdk的工具类简单实现

观察者模式学习之二:使用jdk的自带的工具类实现,与自己实现相比,两者有以下的区别: 1,自己实现,需要定义观察者的接口类和目标对象的接口类.使用java util的工具类,则不需要自己定义观察者和目标对象的接口类了,jdk已经定义好了. 2,自己实现,具体的目标对象类中,实现了接口方法后,还必须要自己实现维护观察者的注册删除信息.但是使用jdk,则不需要了,在 jdk的util下的observable类里面已经帮忙维护好了. 3,目标对象触发观察者的update的通知方式有了变化,自己的实现,

hibernate简单工具类的封装

通过该工具类可以获得hibernate的session对象,并在项目中使用该工具 public class HibernateUtil { private static SessionFactory sessionFactory; //表示构造方法私有化,保证单例模式 private MyHibernateSessionFactory(){ } /** * @return 获取会话工厂 */ public static SessionFactory getSessionFactory() { i

Java学习笔记43(打印流、IO流工具类简单介绍)

打印流: 有两个类:PrintStream,PrintWriter类,两个类的方法一致,区别在于构造器 PrintStream:构造方法:接收File类型,接收字符串文件名,接收字节输出流(OutputStream) PringWriter:构造方法:接收File类型,接收字符串文件名,接收字节输出流(OutputStream),接收字符输出流(Writer) 为其他流添加功能,可以方便地打印各种数据值,不同的是:它永远不会抛出IO异常 方法: package demo; import java

非专业码农 JAVA学习笔记 6java工具类和算法-string

续<非专业码农 JAVA学习笔记 5 java工具类和算法> 五.字符串string 字符串和字符的差别:字符串双引号括起来”n”,字符用单引号括起来,表示一种符号’\n’ 1.string的主要方法和属性 类 方法或者属性 备注 定义string Stirng s=new string(“值”),string s=”值” 属性 string.length:string的长度为字节 方法startswith,endswith s.startwith(“值”)-以值为开头,s.endswith(

JAVA基础学习day17--集合工具类-Collections

一.Collection简述 1.1.Collection与Collections的区别 Collections是集合的静态工具类 Collection:是集合的顶级接口 二.Sort 2.1.sort package com.pb.sort.demo1; import java.util.ArrayList; import java.util.Collections; /** * 对字符串进行自然排序 * */ public class SortDemo1 { public static vo

开发自己的框架——(二)数据库工具类的封装

为了让框架的内容与数据分离,我们把常用的类封装到一个工具类中,当用到这些方法时,就调用这个封装好的类,能够使代码的复用性得到很大的提高.首先,封装数据库相关操作,为了使封装规范化,我们创建一个接口让数据库实现接口中的方法,数据库使用PDO扩展访问数据.数据库接口类 I_DAO.interface.php 1 <?php 2 interface I_DAO 3 { 4 //查询所有数据的功能 5 public function getAll($sql=''); 6 // //查询一条数据 7 pu