lucene全文检索更新

上一篇使用的时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);
}
}
}










评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

starsky20

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值