Lucene3.0 优化操作
什么是Lucene?
我们使用Lucene,主要是做站内搜索,即对一个系统内的资源进行搜索。如BBS、BLOG中的文章搜索,网上商店中的商品搜索等。所以,学完Lucene后我们就可以为自已的项目增加全文检索的功能。跟这个学习内容相关的练习为:给商城商品进行多条件搜索.搜索完毕后,高亮符合条件的信息
使用Lucene的API操作索引库
索引库是一个目录,里面是一些二进制文件,就如同数据库,所有的数据也是以文件的形式存在文件系统中的。我们不能直接操作这些二进制文件,而是使用Lucene提供的API完成相应的操作,就像操作数据库应使用SQL语句一样
对索引库的操作可以分为两种:管理与查询。管理索引库使用IndexWriter,从索引库中查询使用IndexSearcher。Lucene的数据结构为Document与Field。Document代表一条数据,Field代表数据中的一个属性。一个Document中有多个Field,Field的值为String型,因为Lucene只处理文本。
我们只需要把在我们的程序中的对象转成Document,就可以交给Lucene管理了,搜索的结果中的数据列表也是Document的集合。
1,IndexWriter存在的问题
IndexWriter: 则必须要用单态模式独占.因为每一个Writer都需要lock文件,IndexWriter本身是操作类,支持多线程,所以一个全局的IndexWriter即可
下面测试会抛出异常:
@Test
public void testIndexWriter()throws Exception{
IndexWriter indexWriter = new IndexWriter(Configuraction.getDirectory(),Configuraction.getAnalyzer(), MaxFieldLength.LIMITED);
IndexWriter indexWriter2 = new
IndexWriter优化
public class LuceneOperUtil
private static IndexWriter indexWriter = null;
public static IndexWriter getIndexWriter() {
return indexWriter;
}
static {
try {
indexWriter = new IndexWriter(Configuraction.getDirectory(),
Configuraction.getAnalyzer(), MaxFieldLength.LIMITED);
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
indexWriter.optimize();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
closeIndexWriter(indexWriter);
}
}
});
} catch (Exception e) {
new RuntimeException(e);
}
}
public static void closeIndexWriter(IndexWriter indexWriter) {
try {
indexWriter.close();
} catch (Exception e) {
new
2,IndexSearcher存在的问题:
同IndexWriter把IndexSearcher设置为全局代码如下:
public class LuceneOperUtil
private static IndexSearcher indexSearcher=null;
public static IndexSearcher getIndexSearcher() {
return indexSearcher;
}
public static void closeIndexSearcher(IndexSearcher indexSearcher) {
try {
indexSearcher.close();
} catch (Exception e) {
new RuntimeException(e);
}
}
static {
try {
indexSearcher= new IndexSearcher(Configuraction.getDirectory());
// 注册退出程序事件
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
closeIndexSearcher(indexSearcher);
indexWriter.optimize();
}
});
} catch (Exception e) {
new
IndexSearcher全局存在的问题:
IndexSearcher在创建之后的所有的更新操作都是不可见的.所以不能直接像IndexWriter那样用单列模式.
其实在每个方法里面使用的时候创建一个IndexSearcher是没有问题的.
但是那样性能很低. 更好的办法是. 项目共用一个IndexSearcher
当且仅当IndexWriter做了操作后,关闭当前的IndexSearcher,
在用的时候在新创建一个新的IndexSearcher
IndexSearcher优化
public class LuceneOperUtil
private static IndexWriter indexWriter = null;
private static IndexSearcher indexSearcher = null;
// synchronized 避免线程同步创建多个IndexSearcher
public static IndexSearcher getIndexSearcher() {
// 如果IndexSearcher为NULL则创建一个新的IndexSearcher
if (indexSearcher == null) {
synchronized (LuceneOperUtil.class) {
if (indexSearcher == null) {
try {
indexSearcher = new IndexSearcher(Configuraction
.getDirectory());
} catch (Exception e) {
new RuntimeException(e);
}
}
}
}
return indexSearcher;
}
public static IndexWriter getIndexWriter() {
// 销毁原理的IndexSearcher,并不需要立即创建新的 indexSearcher 这样可以节省资源
closeIndexSearcher(indexSearcher);
indexSearcher=null;
return indexWriter;
}
static {
try {
indexWriter = new IndexWriter(Configuraction.getDirectory(),
Configuraction.getAnalyzer(), MaxFieldLength.LIMITED);
// 设置合并因子
indexWriter.setMergeFactor(5);
// 注册退出程序事件
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
closeIndexSearcher(indexSearcher);
indexWriter.optimize();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
LuceneOperUtil.closeIndexWriter(indexWriter);
}
}
});
} catch (Exception e) {
new RuntimeException(e);
}
}
public static void closeIndexWriter(IndexWriter indexWriter) {
try {
if (indexWriter!=null)indexWriter.close();
} catch (Exception e) {
new RuntimeException(e);
}
}
public static void closeIndexSearcher(IndexSearcher indexSearcher) {
try {
if(indexSearcher!=null){
indexSearcher.close();
}
} catch (Exception e) {
new
到此,Lucene3.0优化操作已经完成,仅以此博文记录Lucene学习过程