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学习过程