前言:
lucene全文搜索之一中讲解了lucene开发搜索服务的基本结构,本章将会讲解如何创建索引器、管理索引目录和中文分词器的使用。
包括标准分词器,IKAnalyzer分词器以及两种索引目录的创建
luncene5.5.3集合jar包下载地址:http://download.csdn.net/detail/eguid_1/9677589
一、创建索引器
创建lucene的索引器需要两个要素:一个是分词器,一个是索引目录。
那么就让我们创建这两个实例
1、创建分词器
(1)创建lucene内置分词器
/**
* 创建内置分词器
* @param stopwords CharArraySet停词
* @param stopWords Reader停词
* @param 都为null则返回默认分词器
* @return 分词器
* @throws IOException
*/
public Analyzer createAnalyzer(CharArraySet stopwords, Reader stopWords) throws IOException {
StandardAnalyzer analyzer = null;
if (stopwords != null) {
analyzer = new StandardAnalyzer(stopwords);
} else if (stopWords != null) {
try {
analyzer = new StandardAnalyzer(stopWords);
} catch (IOException e) {
throw e;
}
} else {
analyzer = new StandardAnalyzer();
}
return analyzer;
}
(2)创建IKAnalyzer分词器
IKAnalyzer源码及配置使用请查看使用IK Analyzer中文分词器(修改IK Analyzer源码使其支持lucene5.5.x)
/**
* 创建IKAnalyzer分词器
* @param isSmart -true:智能分词,false:最细粒度分词
* @return
*/
public Analyzer createAnalyzer(boolean isSmart)
{
return new IKAnalyzer(isSmart);
}
2、创建索引目录
索引目录分为文件目录和内存虚拟目录
(1)创建索引文件目录
/**
* 创建文件目录
* @param path -路径
* @param lockFactory -文件锁
* @return Directory -索引目录
* @throws IOException -路径错误导致IO异常
*/
public Directory createDirectory(Path path, LockFactory lockFactory) throws IOException {
FSDirectory dir = null;
// 打开目录
try {
if (lockFactory == null)
dir = FSDirectory.open(path);
else
dir = FSDirectory.open(path, lockFactory);
} catch (IOException e) {
throw e;
}
return dir;
}
/**
* 创建文件目录
* 路径格式:“d:”,“dir”,“search” 等于 “d://dir/search”
* @param lockFactory -文件锁
* @param first -路径
* @param more -路径
* @return Directory -索引目录
* @throws IOException
*/
public Directory createDirectory(LockFactory lockFactory,String first,String ...more) throws IOException{
Path path=FileSystems.getDefault().getPath(first,more);
return createDirectory(path,lockFactory);
}
(2)创建内存虚拟索引目录
public RAMDirectory createRAMDirectory(LockFactory lockFactory, FSDirectory dir, IOContext context)
throws IOException {
RAMDirectory ramDirectory = null;
if (lockFactory != null) {
ramDirectory = new RAMDirectory(lockFactory);
} else if (dir != null && context != null) {
try {
ramDirectory = new RAMDirectory(dir, context);
} catch (IOException e) {
throw e;
}
} else {
ramDirectory = new RAMDirectory();
}
return ramDirectory;
}
创建完了分词器和索引目录,那么我们就可以通过这两个要素构建索引配置
3、创建索引配置
/**
* 根据分词器创建索引配置
* @param analyzer -分词器可以选择默认也可以使用IK或者庖丁
* @param openMode -模式(有三种模式:OpenMode.APPEND -增加;OpenMode.CREATE -创建;OpenMode.CREATE_OR_APPEND -创建和增加;)
* @param commitOnClose -是否关闭时才提交索引
* @return
*/
public IndexWriterConfig createIndexConf(Analyzer analyzer,OpenMode openMode,boolean commitOnClose) {
IndexWriterConfig indexConf = null;
if (analyzer != null) {
indexConf = new IndexWriterConfig(analyzer);
indexConf.setOpenMode(openMode);//一般使用OpenMode.CREATE_OR_APPEND
indexConf.setCommitOnClose(commitOnClose);//默认是true:索引器关闭后才提交索引,false就是手动提交索引
}
return indexConf;
}
创建完索引配置,就可以根据配置创建一个索引器了
4、根据配置和索引目录创建索引
/**
* 创建索引器
* @param dir -索引目录
* @param indexConf -索引配置
* @return IndexWriter 返回索引器
* @throws IOException
*/
public IndexWriter createIndex(Directory dir,IndexWriterConfig indexConf) throws IOException {
IndexWriter indexWriter =null;
try {
indexWriter=new IndexWriter(dir, indexConf);
} catch (IOException e) {
throw e;
}
return indexWriter;
}
有了索引器,我们就可以对索引进行增删查了(没有改)
5、索引器的增删改
重要:lucene中索引只有增删查的API,没有更新/改的API,如果想要更新/改 索引必须先删掉索引再添加
/**
* 增加索引
* @param indexWriter
* @param doc
* @return
*/
public boolean addIndex(IndexWriter indexWriter, Document doc) {
boolean ret = true;
if (indexWriter != null && indexWriter.isOpen() && doc != null) {
try {
indexWriter.addDocument(doc);
indexWriter.commit();//commitOnClose设置为false,这里就需要手动提交,否则关闭索引器后不会自动提交
} catch (IOException e) {
ret = false;
}
}
return ret;
}
/**
* 根据词语删除索引
* @param indexWriter
* @param terms
* @return
*/
public boolean removeIndex(IndexWriter indexWriter, Term ...terms){
boolean ret = true;
if (indexWriter != null && indexWriter.isOpen() && terms != null) {
try {
indexWriter.deleteDocuments(terms); } catch (IOException e) {
ret = false;
}
}
return ret;
}
/**
* 删除搜索结果对应的索引
* @param indexWriter
* @param querys
* @return
*/
public boolean removeIndex(IndexWriter indexWriter, Query ...querys){
boolean ret = true;
if (indexWriter != null && indexWriter.isOpen() && querys != null) {
try {
indexWriter.deleteDocuments(querys);
} catch (IOException e) {
ret = false;
}
}
return ret;
}
不需要使用索引,也可以这样关闭索引
6、关闭索引器
/**
* 关闭索引器
* @param indexWriter
* @param commitOnClose -关闭时是否提交索引(防止正在创建的索引没有及时提交)
* @return true:关闭成功:关闭失败
*/
public boolean close(IndexWriter indexWriter, boolean commitOnClose) {
boolean ret = false;
if (indexWriter != null && indexWriter.isOpen()) {
try {
if (commitOnClose) {
indexWriter.flush();
indexWriter.commit();
}
indexWriter.close();
ret=true;
} catch (IOException e) {
try {
//防止提交时异常导致索引关闭失败,再次尝试关闭
indexWriter.close();
ret=true;
} catch (IOException e1) {
ret=false;
}
}
}
return ret;
}
下一章: