目录结果
一,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();
}
}
}