全文检索之lucene的优化篇--创建索引库

         在上一篇HelloWorld的基础上,建立一个directory的包,添加一个DirectoryTest的测试类,用来根据指定的索引目录创建目录存放指引.

技术分享

    DirectoryTest类中的代码如下,基本上就是在HelloWorld的基础上改改就可以了.

    里面一共三个方法,testDirectory(),测试创建索引库;testDirectoryFSAndRAM(),结合方法1的两种创建方式,优化;testDirectoryOptimize(),在方法2个基础上,研究索引的优化创建,减少创建的索引文件数.

package com.lucene.directory;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.RAMDirectory;
import org.junit.Test;

import com.lucene.units.File2DocumentUtils;

/**
 * 创建索引库
 * @author liu
 *
 */
public class DirectoryTest {

	// 需要查询的文件所在的路径
	String filePath = "F:\\Users\\liuyanling\\workspace\\LuceneDemo\\datasource\\peoplewhocannot.txt";
	// 设置索引存放的路径
	String indexPath = "F:\\Users\\liuyanling\\workspace\\LuceneDemo\\luceneIndex";
	// 设置分词器为标准分词器
	Analyzer analyzer = new StandardAnalyzer();

	/**
	 * 测试,自动建立索引库
	 * @throws Exception 抛出异常
	 */
	@Test
	public void testDirectory() throws Exception {
		//将索引生成到文件系统中(优点:数据永久保存;缺点:操作速度慢)
		Directory dir = FSDirectory.getDirectory(indexPath);
		
		/*//将索引生成到内存中(优点:速度快,缺点:程序关闭,数据清除)
		Directory dir = new RAMDirectory();*/
		
		//所以可以结合:1.生成的时候,生成到内存中;2.关闭的时候,保存起来.(参看下面的方法testDirectoryFSAndRAM)

		Document doc = File2DocumentUtils.file2Document(filePath);
		IndexWriter indexWriter = new IndexWriter(dir, analyzer, true,MaxFieldLength.LIMITED);
		indexWriter.addDocument(doc);

		indexWriter.close();
	}
	
	/**
	 * 测试,启动时读取内存中,退出时保存
	 * @throws Exception 抛出异常
	 */
	@Test
	public void testDirectoryFSAndRAM() throws Exception {
		//创建文件系统的索引库
		Directory fsDir = FSDirectory.getDirectory(indexPath); 
		
		//1.启动时读取
		//构造内存的索引库
		Directory ramDir = new RAMDirectory(fsDir);
		//运行程序时操作ramDir,构造操作内存索引库的索引器
		IndexWriter ramIndexWriter = new IndexWriter(ramDir,analyzer,MaxFieldLength.LIMITED);
		//添加文档Document,将文档创建索引到内存索引库
		Document doc = File2DocumentUtils.file2Document(filePath);
		ramIndexWriter.addDocument(doc);
		ramIndexWriter.close();
		
		//2.退出时保存
		//构造文件系统的索引器,true表示要重写指定的存放索引目录下的索引文件,false则表示在指定存放索引目录下已经存在的索引文件的基础上,向其中继续追加新的索引文件。
		IndexWriter fsIndexWriter = new IndexWriter(fsDir,analyzer,true,MaxFieldLength.LIMITED);
		//不进行优化的添加索引,将内存中的索引库添加到文件系统中
		fsIndexWriter.addIndexesNoOptimize(new Directory[] {ramDir});
		
		//fsIndexWriter.flush();
		//fsIndexWriter.optimize();
		
		fsIndexWriter.close();
	}
	
	/**
	 * 索引生成,优化,合并索引文件,减少生成索引文件数
	 * @throws Exception 
	 */
	@Test
	public void testDirectoryOptimize() throws Exception {
		//创建文件系统的索引库
		Directory fsDir = FSDirectory.getDirectory(indexPath); 
		//构造索引器
		IndexWriter fsIndexWriter = new IndexWriter(fsDir,analyzer,MaxFieldLength.LIMITED);
		//使用索引器,优化的生成索引
		fsIndexWriter.optimize();
		fsIndexWriter.close();
	}

}

    查看运行效果,

     1.先测试testDirectory()Directory dir =FSDirectory.getDirectory(indexPath);  为体现效果,先删除现有的索引文件

技术分享

         测试成功之后

技术分享

    刷新项目,就可以看到新建好的索引.

技术分享

       2.再测试testDirectory()Directory dir = new RAMDirectory();,还是删除索引文件,执行单元测试,成功,但是并没有在文件系统中生成可以看到的索引库。但是可以比较下,两种方法执行的时间,很明显的,在内存中创建速度相当快.

技术分享

        3.由于在将索引生成到文件系统中(优点:数据永久保存;缺点:操作速度慢),而将索引生成到内存中(优点:速度快,缺点:程序关闭,数据清除),所以两者结合的testDirectoryFSAndRAM方法,先看下效果,因为没有索引文件,也不用删除.

    运行成功,时间比只用内存索引库和文件系统索引库都要长,但是这只是将一个Document文件创建成索引,如果是多个,那么该方法是会提高效率的.

技术分享

          并且可以看到索引库也生成了。 

技术分享

          4.现在为了执行优化的创建索引testDirectoryOptimize,先多创建几条索引。现在用testDirectoryFSAndRAM创建了4条索引了。

技术分享

               执行HelloWorldsearch方法,可以看出是4条。

技术分享

     接着执行优化方法

技术分享

     索引文件由原来的48k的记录,变为124k的记录.从结果上看,一是体积减少;2是文件变少.

技术分享

           5.现在知道了,先创建内存索引器来操作文档,结束时保存,在文件多的时候可以起到优化的作用,optimize方法可以减少索引的文件,以及体积,两个结合,可以生成优化的索引.其中,fsIndexWriter.flush();已经过时,把这句注了,运行也是成功的,效果也是有的.

           以上就是lucene的创建索引库.指定索引位置,先在内存中创建索引,然后保存到文件系统中,同时可以进行优化,合并索引文件.下一篇是对于分词器,采用多种分词器,查看他们的分词效果,《全文检索之lucene的优化篇--分词器》

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。