3.5 实例讲解Lucene索引的结构设计

3.2节我们已经运行了一个Lucene建立索引的小程序,这一节我们就以这个小程序为例讲解一下Lucene建立索引的过程。

 1 import java.nio.charset.StandardCharsets;
 2 import java.nio.file.Files;
 3 import java.nio.file.Paths;
 4 import java.io.*;
 5 
 6 import org.apache.lucene.analysis.standard.StandardAnalyzer;
 7 import org.apache.lucene.document.Document;
 8 import org.apache.lucene.document.Field;
 9 import org.apache.lucene.document.StringField;
10 import org.apache.lucene.document.TextField;
11 import org.apache.lucene.index.IndexWriter;
12 import org.apache.lucene.index.IndexWriterConfig;
13 import org.apache.lucene.store.Directory;
14 import org.apache.lucene.store.FSDirectory;
15 import org.apache.lucene.util.Version;
16 
17 /**
18  * @author csl
19  * @description: 
20  * 依赖jar:Lucene-core,lucene-analyzers-common,lucene-queryparser
21  * 作用:简单的索引建立
22  */
23 public class Indexer {
24     public static Version luceneVersion = Version.LATEST;
25     /**
26      * 建立索引
27      */
28     public static void createIndex(){
29         IndexWriter writer = null;
30         try{
31             //1、创建Directory
32             //Directory directory = new RAMDirectory();//创建内存directory
33             Directory directory = FSDirectory.open(Paths.get("index"));//在硬盘上生成Directory00
34             //2、创建IndexWriter
35             IndexWriterConfig iwConfig = new IndexWriterConfig( new StandardAnalyzer());
36             writer = new IndexWriter(directory, iwConfig);
37             //3、创建document对象
38             Document document = null;
39             //4、为document添加field对象
40             File f = new File("raw");//索引源文件位置
41             for (File file:f.listFiles()){
42                     document = new Document();
43                     document.add(new StringField("path", f.getName(),Field.Store.YES));
44                     System.out.println(file.getName());
45                     document.add(new StringField("name", file.getName(),Field.Store.YES));
46                     InputStream stream = Files.newInputStream(Paths.get(file.toString()));
47                     document.add(new TextField("content", new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))));//textField内容会进行分词
48                     //document.add(new TextField("content", new FileReader(file)));  如果不用utf-8编码的话直接用这个就可以了
49                     writer.addDocument(document);
50             }
51         }catch(Exception e){
52             e.printStackTrace();
53         }finally{
54             //6、使用完成后需要将writer进行关闭
55             try {
56                 writer.close();
57             } catch (IOException e) {
58                 e.printStackTrace();
59             }
60         }
61     }
62     public static void main(String[] args) throws IOException
63     {
64         createIndex();
65     }
66 }
View Code

创建索引共六步:

1.创建索引目录。

Directory directory = new RAMDirectory();
Directory directory = FSDirectory.open(Paths.get("index"));
View Code

创建索引目录有两种方式:

  • RAMDirectory类:创建一个内存目录,优点是速度快,缺点是程序退出后索引目录数据就会丢失。
  • FSDirectory类:  创建一个文件目录,该方式创建的索引数据保存在磁盘上,不会因为程序的退出而消失。

下文针对FSDirectory方式来讲解Lucene的基本使用。

2.创建IndexWriter。

1 IndexWriterConfig iwConfig = new IndexWriterConfig( new StandardAnalyzer());
2 IndexWriter writer = new IndexWriter(directory, iwConfig);
View Code

通过IndexWriter对象来创建和维护索引。

IndexWriterConfig对象用来对IndexWriter进行初始配置:配置分词器;配置索引维护的方式;配置用来缓冲文档的RAM大小等。

具体可参照IndexWriterrConfig文档根据需求进行个性化配置。

3. 创建Document。

1 Document doc=new Document();
View Code

Document是Lucene建立索引的基本单元,相当于数据库的关系表。

4. 添加Field。

1 document = new Document();
2                     document.add(new StringField("path", f.getName(),Field.Store.YES));
3                     System.out.println(file.getName());
4                     document.add(new StringField("name", file.getName(),Field.Store.YES));
5                     InputStream stream = Files.newInputStream(Paths.get(file.toString()));
6                     document.add(new TextField("content", new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))));//textField内容会进行分词
7                     //document.add(new TextField("content", new FileReader(file)));  如果不用utf-8编码的话直接用这个就可以了
View Code

Field是Lucene建立索引的最小单元,相当于关系表中的属性。一个Document可以包含多个Field。Document添加Field只需调用Add()方法。

Lucene为我们提供了多种类型的Field,比如IntField, LongField, StringField, TextField等。程序实例中,我们用到了StringField和TextField。我们有必要来了解一下这两种Field的区别,因为这关系到倒排表的建立:

  • StringField:对域进行索引,但不进行分词,将域值作为单一的语汇单元,适用于索引那些不能被分解的域值,如URL,文件路径,电话号码等。参考StringField文档
  • TextField: 对域既索引又分词,Lucene会对这个域进行分词并建立倒排表。参考TextField文档

5.添加Document。

对IndexWriter对象调用addDocument方法将文档添加到索引库中。

6.关闭IndexWriter对象。

把所有的文档都添加到索引库中后,关闭Indexwriter对象。

ps:这篇博客以文集为例形象生动地说明了IndexWriter,Document和Field的关系,大家不妨看一看:例子

关于Lucene的具体索引步骤就介绍到这里~~

.

 

posted @ 2017-05-09 00:34  shulin15  阅读(762)  评论(0编辑  收藏  举报