索引操作仅仅是整个搜索程序的一个简单的步骤。重要的是搜索程序给用户的搜索体验。几乎对所有搜索程序来说,搜索功能都比索引操作细节重要得多。
如何对搜索内容进行建模
文档和域
文档是Lucene索引和搜索的原子单位。域是真正被搜索的内容。如搜索标题为Lucene的文档时,搜索的是域,返回的是文档。
Lucene和MySQL的不同点
Lucene的架构灵活,体现在单一索引可以有多种不同实体的文档;不需要提前设计结构表。
反向规格化
暂时还不理解
索引的过程
3个主要步骤:原始文档转换成文本,分析文本,分析好的文本保存到索引
提取文本、创建文档
使用Tika框架可以轻松从各种格式的文件中提取文本信息。
分析文档
对文档进行索引:调用IndexWriter对象的addDocument方法。
将语汇单元转成小写,去掉停用词。
添加文档
倒排索引不是回答“这个文档中包含哪些单词”,而是“哪些文档包含单词X”。
索引段
Lucene索引包含一个或多个段。每个段都是独立的索引
。
当文档数量达到某个特定的值或文档内存达到某个设定的值,就会创建一个新的索引段
。
搜索索引时,每个段都是单独访问,最后合并
后返回。
基本索引操作
添加文档
删除文档
更新文档
域选项
加权操作
对文档和域进行加权操作。
优化索引
文档数量多,会创建多个索引段。搜索索引时,会搜索每个段,最后合并返回。如果索引比较大的话,要思考如何提高搜索效率?如何优化索引?
优化索引,就是将多个段合并成一个或少量的段
。
IndexWriter提供的4个优化方法:
- optimize()
- optimize(int maxNumSegments)
- optimize(boolean doWait)
- 后台线程调用合并程序
- optimize(int maxNumSegments,boolean doWait)
索引优化会占用较大的CPU和IO,所以索引优化适合的场景是,索引更新不频繁的情况,可以根据情况设置成每几个小时或每周进行一次索引优化。
合并段的过程中,会开辟一个新空间存放新的段,在IndexWriter.commit或关闭IndexWriter之前,旧段不能被删除。
优化期间,索引会占用较大磁盘空间,大约为优化前的3倍。结束后,占用会降低。
Directory子类
- SimpleFSDirectory
- NIOFSDirectory
- MMapDirectory
- RAMDirectory
- FileSwitchDirectory
并发、线程安全、锁机制
IndexReader类拥有只读属性,多个IndexReader可以同时打开一个索引。
对于一个索引来说,一次只能打开一个Writer。创建IndexWriter时,系统就会分配一个文件锁。