本文采用Lucene6.3.0。
建立索引需要5步。
1.创建Directory
Directory这个类这里我们可以暂时理解为主要用来决定索引文件是创建在内存中还是硬盘中。也就是说这个类用来决定存储索引文件的目录。
2.创建IndexWriter
这个类主要用来写索引。
3.创建Document
Document类是用来存储我们索引的文件的信息,包括文件的标题类型大小内容等等。
4.为Document添加域
这里的“域”指的就是文件的标题等等信息。
5.通过IndexWriter写索引
由于以上各种操作会抛出异常,下面给出一个具体实现的Demo:
package com.lucene.first;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Paths;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
public class HelloLucene
{
public void index() throws IOException
{
// 创建Directory :决定索引创建在内存中还是硬盘中
Directory directory = FSDirectory.open(Paths.get("d:/index01"));
// 创建IndexWriter:写索引
IndexWriterConfig writerconfig = new IndexWriterConfig(new StandardAnalyzer());
writerconfig.setOpenMode(OpenMode.CREATE);
IndexWriter writer = null;
try
{
writer = new IndexWriter(directory, writerconfig);
// 3.创建Documents对象:该对象存储文件的信息,包括标题,类型,大小,内容等等的所有
Document document = null;
// 4.为Document添加Field:这里的Field就是文件的标题类型等域
File file = new File("d:/example");
System.out.println(file.listFiles().length);
for (File f : file.listFiles())
{
document = new Document();
document.add(new Field("content", new FileReader(f), TextField.TYPE_NOT_STORED));
document.add(new Field("filename", f.getName(),StringField.TYPE_STORED));
// document.add(new Field("path",f.getAbsolutePath(),ft));
// 5.通过IndexWriter添加文件
writer.addDocument(document);
}
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} finally
{
if (writer != null)
{
try
{
writer.close();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public void search()
{
try
{
// 1.创建Directory
Directory directory = FSDirectory.open(Paths.get("d:/index01"));
// 2.创建IndexReader
IndexReader reader = DirectoryReader.open(directory);
// 3.根据IndexReader创建Searcher
IndexSearcher searcher = new IndexSearcher(reader);
// 4.创建Query
QueryParser parser = new QueryParser("content", new StandardAnalyzer());
// 5.使用Searcher使用返回TopDocs
Query query = parser.parse("Licensed");
System.out.println("Searching for: " + query.toString("contents"));
// 6.根据TopDocs得到ScoreDoc
TopDocs topdocs = searcher.search(query, 5);
// 7.根据ScoreDoc得到具体的Document
ScoreDoc[] sds = topdocs.scoreDocs;
System.out.println(sds.length);
for (ScoreDoc sd : sds)
{
Document d = searcher.doc(sd.doc);
System.out.println(d.toString());
System.out.println("end "+d.get("filename"));
}
// 8.根据Document对象获取具体的值
} catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
上面我们可以看到我们在创建IndexWriter的时候,需要Directory对象和一个分析器对象。
刚开始第一次写的时候,发现建立好索引,但是并不能使用LUKE工具打开,而且在学习到查找的时候,发现并不能正确的查找索引,因此修改建立索引的index()方法。问题出在:我们建立向document对象add Field的时候,必须使用一个FieldType,这个FieldType就是指定分词标准(这里描述可能有点问题,以后随着学习的深入,会修改),内容“content”使用TextField,而文件名使用StringField。这样就能成功建立索引了。下一节会简要学习查找。