lucene + spring

目录结果


一,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();
		}
	}
}







评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值