Lucene3.0 优化操作

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(Configuraction.getDirectory(),Configuraction.getAnalyzer(), MaxFieldLength.LIMITED);
    }

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 RuntimeException(e);
        }
    }
}

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 RuntimeException(e);
        }
    }
}

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 RuntimeException(e);
        }
    }
}

到此,Lucene3.0优化操作已经完成,仅以此博文记录Lucene学习过程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值