上一篇使用的时Object代替实体,由于这样在使用的时候不知道该实体具体是什么,需要强制转换,比较麻烦,本人修改为通过泛型限定对象的类型。
代码如下:
1.公共实体:
public class QueryResult {
private List list;
private int count;
}
public class LuceneUtils{
private static Directory directory;// 建立索引库存储
private static Analyzer analyzer;// 创建分词器
private static IndexWriter indexWriter; // 在程序启动是初始化,建立索引
private static IndexSearcher indexSearcher;// 查询
static {
try {
// 加载配置文件
Properties prop = new Properties();
InputStream inStream = LuceneUtils.class.getClassLoader().getResourceAsStream("conf/lucene/lucene.properties");
//InputStream inStream = ClassLoader.getSystemResourceAsStream("lucene.properties");
prop.load(inStream);
directory = FSDirectory.open(new File("conf/lucene/lucene.properties"));
analyzer = new StandardAnalyzer(Version.LUCENE_30);
// 在程序启动是初始化,建立索引
indexWriter = new IndexWriter(directory, analyzer, MaxFieldLength.LIMITED);
//程序退出时关闭资源
Runtime.getRuntime().addShutdownHook(new Thread(){
public void run(){
try {
indexWriter.close();
} catch (Exception e) {
e.printStackTrace();
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
public static IndexWriter getIndexWriter() {
return indexWriter;
}
public static IndexSearcher getIndexSearch() {
// 执行查询
try {
indexSearcher = new IndexSearcher(directory);
} catch (Exception e) {
throw new RuntimeException(e);
}
return indexSearcher;
}
public static Directory getDirectory() {
return directory;
}
public static Analyzer getAnalyzer() {
return analyzer;
}
}
3.定义一个接口: BaseIndexLucene
public interface BaseIndexLucene<T>{
/**
* 保存实体
*
* @param entity
*/
void save(T obj, CallBackSUD<T> callBack)throws Exception ;
/**
* 更新实体
*
* @param entity
*/
void update(T obj,int id, CallBackSUD<T> callBack)throws Exception ;
/**
* 删除实体
*
* @param id
*/
void delete(Integer id)throws Exception ;
/**查询分页方法
*
* 查询索引库 querString: 查询字符串
* first : 开始位置(分页功能)
* max : 最大数(分页功能)
* parameter :查询指定的字段
* CallBackQuery : 查询函数
* QueryResult : 返回结果集合
* @throws Exception
*/
QueryResult query(String queryString, int first, int max, String[] parameter, CallBackQuery<T> callback)throws Exception ;
/**查询索引库
*
* 查询索引库 querString: 查询字符串
* parameter :查询指定的字段
* CallBackQuery : 查询函数
* QueryResult : 返回结果集合
* Sort : 指定排序条件,按照id升序
* @throws Exception
*/
QueryResult query(String queryString,String[] parameter, CallBackQuery<T> callback)throws Exception ;
/**查询索引库
*
* 查询索引库 querString: 查询字符串
* parameter :查询指定的字段
* CallBackQuery : 查询函数
* QueryResult : 返回结果集合
* @throws Exception
*/
List<T> search(String queryString,String[] parameter, CallBackQuery<T> callback)throws Exception ;
}
4.实现接口的类:
public class BaseIndexLuceneImpl<T> implements BaseIndexLucene<T> {
public interface CallBackQuery<T> {
public abstract QueryResult documentToObject(Document doc, List<T> list, int count) throws Exception;
public abstract List<T> documentToObject(Document doc, List<T> list) throws Exception;
}
public interface CallBackSUD<T> {
public abstract Document objectToDocument(T obj) throws Exception;
}
/**
* //保存到索引库
* CallBackQuery :保存函数
* @return
* @throws Exception
*/
public void save(T obj, CallBackSUD<T> callBack) throws Exception {
try {
// 将Aritcle转为Documnet
Document doc = callBack.objectToDocument(obj);
// 建立索引
IndexWriter indexWriter = LuceneUtils.getIndexWriter();
indexWriter.addDocument(doc);
indexWriter.commit();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 删除索引库 Term 表示制定列中包含的关键字
*
* @return
* @throws Exception
*/
public void delete(Integer id) throws Exception {
String idStr = NumericUtils.intToPrefixCoded(id);
Term term = new Term("id", idStr);
try {
// 建立索引
IndexWriter indexWriter = LuceneUtils.getIndexWriter();
indexWriter.deleteDocuments(term);// 删除指定Term总重的documnet数据
indexWriter.commit();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 修改索引库
* CallBackQuery :更新函数
* @return
* @throws Exception
*/
public void update(T obj,int id, CallBackSUD<T> callBack) throws Exception {
// 创建Term
String idStr = NumericUtils.intToPrefixCoded(id);
Term term = new Term("id", idStr);
try {
// 将Object转换为Document对象
Document doc = callBack.objectToDocument(obj);
// 建立索引
IndexWriter indexWriter = LuceneUtils.getIndexWriter();
indexWriter.updateDocument(term, doc);// 删除指定Term数的documnet数据
indexWriter.commit();
// 先删除,在创建
// indexWriter.deleteDocuments(term);
// indexWriter.addDocument(doc);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**查询分页方法
*
* 查询索引库 querString: 查询字符串
* first : 开始位置(分页功能)
* max : 最大数(分页功能)
* parameter :查询指定的字段
* CallBackQuery : 查询函数
* QueryResult : 返回结果集合
* @throws Exception
*/
public QueryResult query(String queryString, int first, int max, String[] parameter, CallBackQuery<T> callback)throws Exception {
IndexSearcher indexSearcher = null;
try {
// MultiFieldQueryParser:表示可以根据多个字段查询
int totail = first + max;
// 1.把字符串转为Query对象
QueryParser parser = new MultiFieldQueryParser(Version.LUCENE_30, parameter, LuceneUtils.getAnalyzer());
Query query = parser.parse(queryString);
// 2.执行查询
indexSearcher = LuceneUtils.getIndexSearch();
// 指定排序条件
Sort sort = new Sort(new SortField("id", SortField.INT));// 按照id升序
TopDocs topDocs = indexSearcher.search(query, null, totail, sort);// 查询并返回最多的前n条数据
int count = topDocs.totalHits;// 总记录数
ScoreDoc[] scoreDoc = topDocs.scoreDocs;// 最多前n条结果数据
// 生成高亮显示器;设置前缀,后缀,摘要的大小
Formatter formatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");
Scorer scorer = new QueryScorer(query);// 查询条件
Highlighter highlighter = new Highlighter(formatter, scorer);
highlighter.setTextFragmenter(new SimpleFragmenter(100));// 设置摘要的大小
// 3.取出数据
int endIndex = Math.min(totail, scoreDoc.length);
List<T> list = new ArrayList<T>();
for (int i = 0; i < endIndex; i++) {// start
// float score = scoreDoc[i].score;//平均得分
int docId = scoreDoc[i].doc;
Document doc = indexSearcher.doc(docId);
// 进行高亮操作
if (parameter.length > 0) {
for (int j = 0; j < parameter.length; j++) {
// 进行高亮操作,当没有找到关键词时,返回为null
String text = highlighter.getBestFragment(LuceneUtils.getAnalyzer(), parameter[j], doc.get(parameter[j]));
if (text != null) {
doc.getField(parameter[j]).setValue(text);
}
}
}
// 将Document转为Article
callback.documentToObject(doc, list, count);
}// end
// 返回结果集
QueryResult queryResult = new QueryResult(list, count);
return queryResult;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**查询方法
*
* 查询索引库 querString: 查询字符串
* parameter :查询指定的字段
* CallBackQuery : 查询函数
* QueryResult : 返回结果集合
* Sort : 指定排序条件,按照id升序
* @throws Exception
*/
public QueryResult query(String queryString,String[] parameter, CallBackQuery<T> callback) throws Exception {
IndexSearcher indexSearcher = null;
try {
// MultiFieldQueryParser:表示可以根据多个字段查询
// 1.把字符串转为Query对象
QueryParser parser = new MultiFieldQueryParser(Version.LUCENE_30, parameter, LuceneUtils.getAnalyzer());
Query query = parser.parse(queryString);
// 2.执行查询
indexSearcher = LuceneUtils.getIndexSearch();
// 指定排序条件
Sort sort = new Sort(new SortField("id", SortField.INT));// 按照id升序
TopDocs topDocs = indexSearcher.search(query, null, 10000, sort);// 查询并返回最多的前n条数据
int count = topDocs.totalHits;// 总记录数
ScoreDoc[] scoreDoc = topDocs.scoreDocs;// 最多前n条结果数据
// 生成高亮显示器;设置前缀,后缀,摘要的大小
Formatter formatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");
Scorer scorer = new QueryScorer(query);// 查询条件
Highlighter highlighter = new Highlighter(formatter, scorer);
highlighter.setTextFragmenter(new SimpleFragmenter(100));// 设置摘要的大小
// 3.取出数据
List<T> list = new ArrayList<T>();
for (int i = 0; i < scoreDoc.length; i++) {// start
int docId = scoreDoc[i].doc;
Document doc = indexSearcher.doc(docId);
// 进行高亮操作
if (parameter.length > 0) {
for (int j = 0; j < parameter.length; j++) {
// 进行高亮操作,当没有找到关键词时,返回为null
String text = highlighter.getBestFragment(LuceneUtils.getAnalyzer(), parameter[j], doc.get(parameter[j]));
if (text != null) {
doc.getField(parameter[j]).setValue(text);
}
}
}
// 将Document转为Article
callback.documentToObject(doc, list, count);
}// end
// 返回结果集
QueryResult queryResult = new QueryResult(list, count);
return queryResult;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**无分页功能
*
* 查询索引库 querString: 查询字符串
* parameter :查询指定的字段
* CallBackQuery : 查询函数
* QueryResult : 返回结果集合
* score : 默认按照相关度得分排序
* @throws Exception
*/
public List<T> search(String queryString, String[] parameter, CallBackQuery<T> callback)throws Exception {
IndexSearcher indexSearcher = null;
try {
// MultiFieldQueryParser:表示可以根据多个字段查询
// 1.把字符串转为Query对象
QueryParser parser = new MultiFieldQueryParser(Version.LUCENE_30, parameter, LuceneUtils.getAnalyzer());
Query query = parser.parse(queryString);
// 2.执行查询
indexSearcher = LuceneUtils.getIndexSearch();
// 指定排序条件
TopDocs topDocs = indexSearcher.search(query,100);// 查询并返回最多的前n条数据
//int count = topDocs.totalHits;// 总记录数
ScoreDoc[] scoreDoc = topDocs.scoreDocs;// 最多前n条结果数据
// 生成高亮显示器;设置前缀,后缀,摘要的大小
Formatter formatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");
Scorer scorer = new QueryScorer(query);// 查询条件
Highlighter highlighter = new Highlighter(formatter, scorer);
highlighter.setTextFragmenter(new SimpleFragmenter(100));// 设置摘要的大小
// 3.取出最小的数据
List<T> list = new ArrayList<T>();
for (int i = 0; i < scoreDoc.length; i++) {// start
//float score = scoreDoc[i].score;//平均得分
int docId = scoreDoc[i].doc;
Document doc = indexSearcher.doc(docId);
/* // 进行高亮操作
if (parameter.length > 0) {
for (int j = 0; j < parameter.length; j++) {
// 进行高亮操作,当没有找到关键词时,返回为null
String text = highlighter.getBestFragment(LuceneUtils.getAnalyzer(), parameter[j], doc.get(parameter[j]));
if (text != null) {
doc.getField(parameter[j]).setValue(text);
}
}
}*/
// 将Document转为Article
callback.documentToObject(doc, list);
}// end
return (List<T>) list;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}