建立索引库

发表时间:2017-07-18 18:59:09 浏览量( 39 ) 留言数( 0 )

学习目标:

1、了解Lucene的建立索引的类

2、掌握Lucene的建立索引的方法


学习过程:

要是用lucene作为查询,必须先对原始的文本进行索引,才能提供查询,建立索引库是查询的基础,好的索引即可方便查询,也可以提高查询的效率,这里只是通过lucene的示例对原始的文本进行简单的所以,可能会有很多大家不理解的地方,大家可以先跳过,以后我们在慢慢的深入研究。建立索引库主要需要用到下面几个类

IndexWriter

是索引过程的核心类,这个类服装创建新的索引或者打开已有的索引,后面我们也会学到这个类也可以对索引的文档进行删除和修改等操作。

Directory

这个类抽象描述了Lucene索引的位置,它有好几个实现类,我们可以使用FSDirectory.open方法获得索引的存放路径,它会比较智能的判断使用那个实现类是最佳的。

Analyzer

文本在索引之前是需要先分析的,这个分析过程是最复杂也是最重要的一个环节,因为程序需要通过这个分析器去理解不过国家的不同语言。

Document

Document对象是一些Field的集合,你可以理解成为就是数据库里面的一行数据,不过它不需要向数据库那样需要实现定义数据机结构,使用非常灵活,

Field

一个Document包含一个或者多个不同命名的Filed,每一个Field及保存了一个Filed的域名,同时也保存了值。

一、准备原始文档

下面我们就通过上面的这些类对大量的文本建立一个索引,为了更好的演示Lucene的作用,我们首先需要准备一些原始的文档内容。你可以到网上下载一篇长篇小说,然后对其进行分割处理成为一个一个的小文本。

加压之后文档内容很大,有10M,把它复制到d盘下,并重命名为test.txt。下面我们先对其进行分割,因为更加类似我们平时要处理的单独的一篇文章。代码如下:

   public class Pre {

	public void pre(String sourceFile, String targetPath) {
		try {
			BufferedReader read = new BufferedReader(new FileReader(new File(
					sourceFile)));

			String line = read.readLine();
			int filename=0;
			while (line != null) {
				
				BufferedWriter write = new BufferedWriter(new FileWriter(
						new File(targetPath+"//lucene"+filename+".txt")));
		
				for(int i=0;i<10;i++){
					write.write(line+"
");
					line = read.readLine();
					if(line==null){
						break;
					}
                }
				write.flush();
				write.close();
				filename++;
			}
			read.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		Pre pre=new Pre();
		pre.pre("d://test.txt", "d://lucene//");

	}

}

运行上面的代码,这时候在d:/lucene就可以看到很多小的文本了。

二、建立索引

1、导包

下载最新版的Lucene,打开其说明文档就会有一个完整的示例,按照这个示例的方法,先测试一下,当然我们第一步还是先要导包,运行Lucene需要三个包,到相关的目录复制就可以了,分别是:lucene-analyzers-common-4.6.0.jar,lucene-core-4.6.0.jar,lucene-queryparser-4.6.0.jar。

2、建立索引

下面我们就可以对其进行索引了。代码如下:

   public class IndexFile {

	public void createIndex(String sourcePath, String indexPath, boolean create) {

		Date start = new Date();
		try {
			System.out.println("Indexing to directory '" + indexPath + "'...");

			Directory dir = FSDirectory.open(new File(indexPath));
			Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_46);
			IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_46,
					analyzer);

			// 是否是新建
			if (create) {
				// Create a new index in the directory, removing any
				// previously indexed documents:
				// 删除之前的多有的document
				iwc.setOpenMode(OpenMode.CREATE);
			} else {
				// Add new documents to an existing index:
				// 添加一个新的documents
				iwc.setOpenMode(OpenMode.CREATE_OR_APPEND);
			}

			IndexWriter writer = new IndexWriter(dir, iwc);
			// 逐个文件读取和写入
			indexDocs(writer, new File(sourcePath));

			writer.close();

			Date end = new Date();
			System.out.println(end.getTime() - start.getTime()
					+ " total milliseconds");

		} catch (Exception e) {
			// TODO: handle exception
		}

	}

	public void indexDocs(IndexWriter writer, File file) throws IOException {
		// do not try to index files that cannot be read
		if (file.canRead()) {
			// 如果是目录 就进入这个目录递归的继续索引
			if (file.isDirectory()) {
				String[] files = file.list();
				System.out.println(files.length);
				// an IO error could occur
				if (files != null) {
					for (int i = 0; i < files.length; i++) {
						indexDocs(writer, new File(file, files[i]));
					}
				}
			} else {

				FileInputStream fis;
				try {
					fis = new FileInputStream(file);
				} catch (FileNotFoundException fnfe) {
					return;
				}

				try {

					// make a new, empty document
					Document doc = new Document();

			
					Field pathField = new StringField("path", file.getPath(),
							Field.Store.YES);
					doc.add(pathField);

					doc.add(new LongField("modified", file.lastModified(),
							Field.Store.YES));

					doc.add(new TextField("contents", new BufferedReader(
							new InputStreamReader(fis, "UTF-8"))));

					if (writer.getConfig().getOpenMode() == OpenMode.CREATE) {

						System.out.println("adding " + file);
						writer.addDocument(doc);
					} else {

						System.out.println("updating " + file);
						writer.updateDocument(new Term("path", file.getPath()),
								doc);
					}

				} finally {
					fis.close();
				}
			}
		}
	}

	public static void main(String[] args) {
		IndexFile indexFile = new IndexFile();

		indexFile.createIndex("d://lucene//", "d://luceneindex", true);
	}

}

运行上面的代码就可以看到在d:/luceneindex目录下建立了很多索引文件,lucene使用倒排序的方式组织索引所以大家打开这些文件暂时也看不懂里面的内容。