在开始之前,先对IndexWriter的所需要考虑的问题有个大致的了解。IndexWriter主要负责索引数据写入,所以,增删改是主要需要考虑的问题;其次,由于写入的过程涉及成功失败的问题,所以,事务以及二阶段事务也是应该考虑到的;再来就是需要写入过程有最大的吞吐量,所以,还存在缓存以及刷新的问题;另外,如何让多线程高效并发访问索引也是要思考的;还有,通常查找内容的数量都非常庞大,如何管理索引过程中的内存以及磁盘消耗也是值得考虑的事情。接下来的文章,会对这些问题分别分析。
索引的增删改
增加,下面的api主要是加入一个或多个文档,以及对这篇文档使用的analyzer。实际上,增加文档在背后是调用了更新这一操作。它所提供的接口无非是单文档和多文档,有分析器和无分析器的区别。
public void addDocument(IndexDocument doc) throws IOException
public void addDocument(IndexDocument doc, Analyzer analyzer) throws IOException
public void addDocuments(Iterable<? extends IndexDocument> docs) throws IOException
public void addDocuments(Iterable<? extends IndexDocument> docs, Analyzer analyzer) throws IOException
更新,需要明白的是,更新并非像数据库一样,而是一个先删除后增加的过程
public void updateDocuments(Term delTerm, Iterable<? extends IndexDocument> docs) throws IOException
public void updateDocuments(Term delTerm, Iterable<? extends IndexDocument> docs, Analyzer analyzer) throws IOException
public void updateDocument(Term term, IndexDocument doc) throws IOException
public void updateDocument(Term term, IndexDocument doc, Analyzer analyzer)
throws IOException
删除,第一种方式是删除所有包含这个词的文档,第二种方式是删除所有包含这几个词的文档,第三种方式是删除所有符合该查询的文档,第四种方式是删除所有符合这组查询的文档,第五种方式是直接删除所有文档
public void deleteDocuments(Term term) throws IOException
public void deleteDocuments(Term... terms) throws IOException
public void deleteDocuments(Query query) throws IOException
public void deleteDocuments(Query... queries) throws IOException
public void deleteAll() throws IOException
在更深入的讨论前先理下索引的链式结构,因为这个神奇的结构经常把人搞得云里雾里。默认的索引链在DocumentsWriterPerThread中有初始化。代码如下:
static final IndexingChain defaultIndexingChain = new IndexingChain() {
@Override
DocConsumer getChain(DocumentsWriterPerThread documentsWriterPerThread) {
/*
This is the current indexing chain:
DocConsumer / DocConsumerPerThread
--> code: DocFieldProcessor
--> DocFieldConsumer / DocFieldConsumerPerField
--> code: DocFieldConsumers / DocFieldConsumersPerField
--> code: DocInverter / DocInverterPerField
-->