目录结果
一,lucene的索引工具类
public class IndexUtils { private static final Logger LOGGER = Logger.getLogger(IndexUtils.class); // 庖丁解牛分词器(单例) private static Analyzer ANALYZER = null; // 索引的路径 private static final String indexPath = SysConfig.getProperty("indexPath"); static { if (ANALYZER == null) { ANALYZER = new PaodingAnalyzer(); } } /** * 得到庖丁解牛分词器 * * @return */ public static Analyzer getAnalyzer() { return ANALYZER; } /** * 得到路径对象 * * @param path 相对路径 * @return */ public static Directory getDirectory(String path) { Directory directory = null; try { directory = FSDirectory.open(new File(path)); } catch (IOException e) { e.printStackTrace(); } return directory; } /** * 得到读索引类 * @return */ public static IndexReader getIndexReader() { IndexReader reader = null; try { reader = IndexReader.open(getDirectory(indexPath)); } catch (CorruptIndexException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return reader; } /** * 得到些索引类 * @return */ public static IndexWriter getIndexWriter() { IndexWriter writer = null; try { writer = new IndexWriter(getDirectory(indexPath), new IndexWriterConfig(Version.LUCENE_36, ANALYZER)); } catch (CorruptIndexException e) { e.printStackTrace(); } catch (LockObtainFailedException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return writer; } /** * 得到索引搜索类 * @return */ public static IndexSearcher getIndexSearcher() { IndexSearcher searcher = null; try { searcher = new IndexSearcher(getIndexReader()); } catch (Exception e) { e.printStackTrace(); } return searcher; } /** * 建立索引 * @param bean 需要建立索引的bean * @param excludField 不建立索引的bean字段名称 * @param analyzedFiled 建立进行分词的bean字段名称 * @param flagStr 标志字符串 如资讯以ZX开头 ,就传入ZX */ public static void createIndex(Object bean,String[] excludField,String[] analyzedFiled,String flagStr) { // 得到输出索引类 IndexWriter indexWriter = null; // 索引类 try { indexWriter = getIndexWriter(); Document doc = new Document(); //新增标志 doc.add(new Field("flagId",flagStr+StringUtils.getUUIDStr(),Store.YES,Index.NOT_ANALYZED)); //对象的字段信息 java.lang.reflect.Field[] fields = bean.getClass().getDeclaredFields(); //建立索引 for (java.lang.reflect.Field field : fields) { field.setAccessible(true); if(!StringUtils.isInArray(field.getName(),excludField) && excludField != null){ addField(field,bean,doc,Store.YES, StringUtils.isInArray(field.getName(), analyzedFiled) ? Index.ANALYZED : Index.NOT_ANALYZED); } field.setAccessible(false); } indexWriter.addDocument(doc); } catch (CorruptIndexException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }catch (IllegalArgumentException e) { e.printStackTrace(); } finally { try { // 关闭writer indexWriter.close(); } catch (CorruptIndexException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } /** * 优化索引 */ public static void mergeIndex() { IndexWriter indexWriter = null; // 强制优化索引 try { indexWriter = getIndexWriter(); indexWriter.forceMerge(1); } catch (CorruptIndexException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { indexWriter.close(); } catch (CorruptIndexException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } /** * 更新索引 * @param bean 需要建立索引的bean * @param excludField 不建立索引的bean字段名称 * @param notAnalyzedFiled 建立进行分词的bean字段名称 * @param term 查找索引库中的term */ public static void updateIndex(Object bean,String[] excludField,String[] analyzedFiled,Term term) { // 得到输出索引类 IndexWriter indexWriter = null; // 索引类 try { indexWriter = getIndexWriter(); Document doc = new Document(); //对象的字段信息 java.lang.reflect.Field[] fields = bean.getClass().getDeclaredFields(); //建立索引 for (java.lang.reflect.Field field : fields) { field.setAccessible(true); if(!StringUtils.isInArray(field.getName(),excludField) && excludField != null){ addField(field,bean,doc,Store.YES, StringUtils.isInArray(field.getName(), analyzedFiled) ? Index.ANALYZED : Index.NOT_ANALYZED); } field.setAccessible(false); } //更新索引 indexWriter.updateDocument(term, doc, ANALYZER); indexWriter.forceMerge(1); } catch (CorruptIndexException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }catch (IllegalArgumentException e) { e.printStackTrace(); } finally { try { // 关闭writer indexWriter.close(); } catch (CorruptIndexException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } /** * 删除全部索引文件 */ public static void deleteAll() { IndexWriter writer = null; try { writer = getIndexWriter(); writer.deleteAll(); } catch (IOException e) { e.printStackTrace(); } finally { try { writer.close(); } catch (CorruptIndexException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } /** * 根据条件删除索引 * @param term 条件 */ public static void delete(Term term) { IndexWriter writer = null; try { writer = getIndexWriter(); writer.deleteDocuments(term); writer.forceMerge(1); } catch (IOException e) { e.printStackTrace(); } finally { try { writer.close(); } catch (CorruptIndexException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } /** * 查询 * @param fieldname 字段名 * @param queryText 查询内容 * @return * @throws ParseException */ public static Query getQuery(String fieldname,String queryText) throws ParseException{ queryText = queryText.trim(); if (queryText.length() > 1) { QueryParser queryParser = new QueryParser(Version.LUCENE_36, fieldname, IndexUtils.getAnalyzer()); return queryParser.parse(queryText); }else{ return new WildcardQuery(new Term(fieldname,"*"+queryText+"*")); } } /** * 类型的映射 * * @param field * @param obj * @param rs * @throws IllegalArgumentException * @throws IllegalAccessException * @throws SQLException */ private static void addField(java.lang.reflect.Field field, Object bean,Document doc,Store store, Index index) { String typeName = field.getType().getName(); // 得到字段类型 String fieldName = field.getName(); //字段名 // 设置值的 // (所属对象,值), ResultSet的getString/getInt...里面的字段名是不分大小写的 try { if (typeName.equals("float") || typeName.equals("java.lang.Float")) { doc.add(new NumericField(fieldName,store,true).setFloatValue(field.get(bean)==null || "".equals(field.get(bean)) ? 0 : Float.parseFloat(field.get(bean).toString()))); } else if (typeName.equals("double") || typeName.equals("java.lang.Double")) { doc.add(new NumericField(fieldName,store,true).setDoubleValue(field.get(bean)==null || "".equals(field.get(bean)) ? 0 : Double.parseDouble(field.get(bean).toString()))); } else if (typeName.equals("java.util.Date")) { doc.add(new Field(field.getName(),field.get(bean) == null ? "": DateUtils.formatDate((Date)field.get(bean),"yyyy-MM-dd HH:mm:ss") ,store,index)); } else { doc.add(new Field(fieldName,field.get(bean)==null || "".equals(field.get(bean)) ? "": field.get(bean).toString() ,store,index)); } } catch (IllegalArgumentException e) { LOGGER.error("============>IdexUtils:addField [fieldTypeName:"+typeName+"] " + "[fieldName:"+field.getName()+"] [error:"+e.getMessage()+"]"); e.printStackTrace(); } catch (IllegalAccessException e) { LOGGER.error("============>IdexUtils:addField [fieldTypeName:"+typeName+"] " + "[fieldName:"+field.getName()+"] [error:"+e.getMessage()+"]"); e.printStackTrace(); } } }
package com.hwt.lucene.index; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.Field.Index; import org.apache.lucene.document.Field.Store; /** * 文件类型的搜索 * @author 黄文韬 * */ public class FileDocument { /** * 将文件转换为一个document对象 * @param file 文件 * @return */ public Document fileToDocument(File file){ Document document=new Document(); document.add(new Field("name", file.getName(), Store.YES, Index.ANALYZED)); document.add(new Field("content", this.readFileRetStr(file), Store.YES, Index.ANALYZED)); return document; } /** * 将名字、内容字段转为document * @param content 内容 * @param name 文件名字 * @return */ public Document stringToDocumet(String name,String content){ Document document=new Document(); document.add(new Field("name",name, Store.YES, Index.ANALYZED)); document.add(new Field("content", content, Store.YES, Index.ANALYZED)); return document; } /** * 将文件内容转为string类型 * @param file 文件 * @return */ public String readFileRetStr(File file){ FileInputStream fStream = null; String tempStr = ""; StringBuffer sBuffer = new StringBuffer(); try { fStream = new FileInputStream(file); BufferedReader bReader=new BufferedReader(new InputStreamReader(fStream,"UTF-8")); while((tempStr=bReader.readLine())!=null){ sBuffer.append(tempStr); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { fStream.close(); } catch (IOException e) { e.printStackTrace(); } } return sBuffer.toString(); } }
三,分页参数类
public class PagingIndexParams { private Integer nextPage;// 需要显示内容的页码 private Integer pageSize; // 每页的条数 private Query query; // lucene查询对象 private Sort sort; // 排序对象 private Class clazz; //封装的bean //设置下一页的页码 public Integer getNextPage() { if (nextPage == null || "".equals(nextPage)) { return 1; }else { return nextPage; } } public void setNextPage(Integer nextPage) { this.nextPage = nextPage; } public Integer getPageSize() { if (pageSize == null || "".equals(pageSize)) { int configSize = Integer.parseInt(SysConfig.getProperty("pageSize")); return configSize; }else { return pageSize; } } //设置每页条数 public void setPageSize(Integer pageSize) { this.pageSize = pageSize; } public Query getQuery() { return query; } public void setQuery(Query query) { this.query = query; } public Sort getSort() { return sort; } public void setSort(Sort sort) { this.sort = sort; } public Class getClazz() { return clazz; } public void setClazz(Class clazz) { this.clazz = clazz; } }
四,分页结果封装类
public class PagingIndexResults { private int currentPage; //当前页码 private int totalSize; //总共条数 private int totalPages; //总共页数 private Integer pageSize; // 每页的条数 private List list ; //结果集 public Integer getPageSize() { return pageSize; } public void setPageSize(Integer pageSize) { this.pageSize = pageSize; } public int getCurrentPage() { return currentPage; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } public int getTotalSize() { return totalSize; } public void setTotalSize(int totalSize) { this.totalSize = totalSize; } public int getTotalPages() { return totalPages; } public void setTotalPages(int totalPages) { this.totalPages = totalPages; } public List getList() { return list; } public void setList(List list) { this.list = list; } }
</pre><p><pre name="code" class="java">@Component public class PagingLucene { private static final Logger LOGGER = Logger.getLogger(PagingLucene.class); //初始化的查询大小 private int initSize = 100; /** * 分页方法 * @param params 分页参数封装类 * @param highLightFields 需要高亮显示的字段 * @return */ public PagingIndexResults paging(PagingIndexParams params,String[] highLightFields){ IndexSearcher searcher = IndexUtils.getIndexSearcher(); // 显示条数 int querySize = (params.getNextPage() * params.getPageSize() / initSize + 1) * initSize; // 设置查询、查询显示的条数、排序对象 TopDocs topDocs = null; try { if (params.getSort() != null) { topDocs = searcher.search(params.getQuery(), querySize, params.getSort()); } else { topDocs = searcher.search(params.getQuery(), querySize); } } catch (IOException e) { e.printStackTrace(); } // 总共记录条数 int totalNum = topDocs.totalHits; // 总页数 int pageNum = totalNum % params.getPageSize() == 0 ? totalNum / params.getPageSize() : totalNum / params.getPageSize() + 1; // 如果当前页超出了页码范围 int page = params.getNextPage(); if (page > pageNum) { params.setNextPage(pageNum); } // 得到记录集 ScoreDoc[] docs = topDocs.scoreDocs; //起始位置和终止位置 int startSize = (page - 1)*params.getPageSize(); int endSize = startSize + params.getPageSize() > totalNum ? totalNum : startSize + params.getPageSize(); //得到本页的结果集 List beanList = new ArrayList(); Class beanClass = params.getClazz(); try { for (int i = startSize; i < endSize; i++) { Document document = searcher.doc(docs[i].doc); try { //实例化分页bean对象 Object object = beanClass.newInstance(); //得到字段集 Field[] fields = beanClass.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); //高亮显示 if (StringUtils.isInArray(field.getName(), highLightFields)) { //定义高亮显示的样式 SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<font color='red'><b>", "</b></font>"); String fieldNameStr = field.getName(); String documentStr = document.get(fieldNameStr); /*Fieldable f = document.getFieldable(fieldNameStr); if(f instanceof NumericField ) { NumericField nf = (NumericField )f; Long date = (Long)nf.getNumericValue(); }*/ //按分数高低 QueryScorer scorer = new QueryScorer(params.getQuery()); Fragmenter fragmenter = new SimpleFragmenter(100); Highlighter highlight = new Highlighter(formatter,scorer); highlight.setTextFragmenter(fragmenter); try { String hightHtmlStr = highlight.getBestFragment(IndexUtils.getAnalyzer(), fieldNameStr, documentStr); this.typeMapper(field, object, StringUtils.isBlank(hightHtmlStr)?documentStr:hightHtmlStr); } catch (IllegalArgumentException e) { e.printStackTrace(); }catch (InvalidTokenOffsetsException e) { e.printStackTrace(); } }else { //如果不进行高亮显示 this.typeMapper(field, object, document.get(field.getName())); //field.set(object, document.get(field.getName())); } field.setAccessible(false); } beanList.add(object); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } catch (CorruptIndexException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } PagingIndexResults results = new PagingIndexResults(); results.setCurrentPage(params.getNextPage());//当前页 results.setPageSize(params.getPageSize());//每页大小 results.setTotalPages(pageNum);//总页数 results.setTotalSize(totalNum);//总条数 results.setList(beanList); //结果集 return results; } /** * 查询指定条数的记录 * @param query 查询对象 * @param termSize 显示的条数 * @param sort 排序对象 (可为空) * @param clazz 需要封装的javaBean * @param highLightFields 需要高亮显示的字段数组 * @return javabean集合 */ public List search(Query query,int termSize,Sort sort,Class clazz,String[] highLightFields){ IndexSearcher searcher = IndexUtils.getIndexSearcher(); // 设置查询、查询显示的条数、排序对象 TopDocs topDocs = null; try { if (sort != null) { topDocs = searcher.search(query, termSize, sort); } else { topDocs = searcher.search(query, termSize); } } catch (IOException e) { e.printStackTrace(); } // 得到记录集 ScoreDoc[] docs = topDocs.scoreDocs; //得到本页的结果集 List beanList = new ArrayList(); Class beanClass = clazz; try { termSize = topDocs.totalHits > termSize ? termSize : topDocs.totalHits; for (int i = 0; i < termSize; i++) { Document document = searcher.doc(docs[i].doc); try { //实例化分页bean对象 Object object = beanClass.newInstance(); //得到字段集 Field[] fields = beanClass.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); //高亮显示 if (StringUtils.isInArray(field.getName(), highLightFields)) { //定义高亮显示的样式 SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<font color='red'><b>", "</b></font>"); String fieldNameStr = field.getName(); String documentStr = document.get(fieldNameStr); //按分数高低 QueryScorer scorer = new QueryScorer(query); SimpleFragmenter fragmenter = new SimpleFragmenter(100); Highlighter highlight=new Highlighter(formatter,scorer); highlight.setTextFragmenter(fragmenter); try { String hightHtmlStr = highlight.getBestFragment(IndexUtils.getAnalyzer(), fieldNameStr, documentStr); this.typeMapper(field, object, StringUtils.isBlank(hightHtmlStr)?documentStr:hightHtmlStr); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvalidTokenOffsetsException e) { e.printStackTrace(); } }else { //如果不进行高亮显示 this.typeMapper(field, object, document.get(field.getName())); } field.setAccessible(false); } //将对象加入到list中 beanList.add(object); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } catch (CorruptIndexException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return beanList; } /** * 查询符合条件的记录条数 * @param query 查询对象 * @return 记录条数 */ public Integer searchTermNum(Query query){ IndexSearcher searcher = IndexUtils.getIndexSearcher(); int num = 0; try { TopDocs topDocs = searcher.search(query, 1); num = topDocs.totalHits; } catch (IOException e) { e.printStackTrace(); } return num; } /** * 类型的映射 * * @param field * @param obj * @param rs * @throws IllegalArgumentException * @throws IllegalAccessException * @throws SQLException */ private void typeMapper(Field field, Object obj, String rs) { String typeName = field.getType().getName(); // 得到字段类型 // 设置值的 // (所属对象,值), ResultSet的getString/getInt...里面的字段名是不分大小写的 try { if (typeName.equals("java.lang.String")) { field.set(obj, rs); } else if (typeName.equals("int") || typeName.equals("java.lang.Integer")) { field.set(obj, StringUtils.isBlank(rs) ? 0 : Integer.parseInt(rs)); } else if (typeName.equals("long") || typeName.equals("java.lang.Long")) { field.set(obj, StringUtils.isBlank(rs) ? 0 : Long.parseLong(rs)); } else if (typeName.equals("float") || typeName.equals("java.lang.Float")) { field.set(obj, StringUtils.isBlank(rs) ? 0 : Float.parseFloat(rs)); } else if (typeName.equals("double") || typeName.equals("java.lang.Double")) { field.set(obj, StringUtils.isBlank(rs) ? 0 : Double.parseDouble(rs)); } else if (typeName.equals("boolean") || typeName.equals("java.lang.Boolean")) { field.set(obj, StringUtils.isBlank(rs) ? 0 : Boolean.parseBoolean(rs)); } else if (typeName.equals("java.util.Date")) { field.set(obj, StringUtils.isNotBlank(rs) ? DateUtils.formateStrToDate(rs, "yyyy-MM-dd") : null); } else { } } catch (IllegalArgumentException e) { LOGGER.error("============>pagingLucene:typeMapper [fieldTypeName:"+typeName+"] " + "[fieldName:"+field.getName()+"] [error:"+e.getMessage()+"]"); e.printStackTrace(); } catch (IllegalAccessException e) { LOGGER.error("============>pagingLucene:typeMapper [fieldTypeName:"+typeName+"] " + "[fieldName:"+field.getName()+"] [error:"+e.getMessage()+"]"); e.printStackTrace(); } } }