索引段的存储结构见[1]P35。如果使用混合文件格式,使用
IndexWriter.setUseCompoundFile修改,则存储结构会被压缩成一个单一文件: _X.cfs。
2.1 文档的构建
addDocument(Document,[Analyzer]);[1]P35
deleteDocuments();[1]P38 lucene并不是立即删除,而是放在缓存中,周期性刷新,删除完成后,存储空间也不会立即释放,而会将该文档标记为\删除\。 maxDoc()返回索引中被删除和未被删除的文档总数。 numDocs()但会索引中未被删除的文档总数。
updateDocument(Term,Document,[Analyzer])首先删除包含Term变量的所有文档,然后添加文档。
2.2 域选项
2.2.1域索引选项
? Index.ANALYZED 使用分析器将域值分解成独立的语汇单元流,并使每个语汇
单元能被政索.该选项适用于普通文本域(如正文.标题、摘要等). ? Index.NOT_ANALYZED
对域进行索引,但不对String值进行分析.该操作实
际上将域值作为单一语汇单元并使之能被搜索。该选项适用于索引那些不能被分解的域值,如URL、文件路径、日期、人名、社保号码和电话号码等.该选项尤其适用 于“精确匹配”搜索。 ? Index.ANALYZED_ NO_NORMS
这是 Index.ANALYZED选项的一个变体,它
不会在索引中存储norms信息。norms记录了索引中的index-time boost信息,但是当 你进行搜索时可能会比较耗费内存。有关norms的详细内容详见[1]2.5.3小节。
? Index.NOT_ANALYZED_NO_NORMS
与 Index.NOT_ANALYZED 选项类似,但
也是不存储norms.该选项常用于在搜索期间节省索引空间和减少内存耗费,因 为single-token域并不需要norms信息,除非它们已被进行加权操作。 ? index. NO
使对应的域值不被搜索.
当Lucene建立起倒排索引后,默认情况下它会保存所有必要信息以实施Vector Space Model。该Model需要计算文档中出现的term数,以及它们出现的位置(这是必要的,比 如通过词组搜索时用到)。但有时候这些域只是在布尔搜索时用到,
它们并不为相关评分 做贡献,一个常见的例子是,域只是被用作过滤,如权限过滤和日期过滤。在这种情况下, 可以通过调用 Field.setOmitTermFreqAndPositions (true)方法让Lucene跳过对该项 的出现频率和出现位置的索引。该方法可以节省一些索引在磁盘上的存储空间,还可以加 速搜索和过滤过程,但会悄悄地阻止需要位置信息的搜索,如阻止PhraseQuery和 SpanQuery类的运行。
2.2.2域存储选项
? Store. YES——指定存储域值。该情况下,原始的字符串值全部被保存在索引
中,并可以由IndexReader类恢复.该选项对于需要展示搜索结果的一些域很 有用(如URL、标題或数据库主键).如果索引的大小在搜索程序考虑之列的 话,不要存储太大的域值,因为存储这些域值会消耗掉索引的存储空间. ? Store.NO
指定不存储域值.该选项通常跟Index.ANALYZED选项共同用来索
引大的文本域值,通常这些域值不用恢复为初始格式,如Web页面的正文, 或其他类型的文本文档.
Lucene包含一个很实用的工具类,CompressionTools,该类提供静态方法压缩和 解压字节数组。该类运行时会在后台调用Java内置的java.util.zip类。你可以使用 CompressionTools在存储域值之前对它进行压缩。注意,尽管该方法可以为索引节省—些空间,但节省的幅度跟域值的可被压缩程度有关,而且该方法会降低索引和搜索速度。这样其实就是通过消耗更多CPU计算能力来换取更多的磁盘空间,对于很多程序 来说,需要仔细权衡一下。如果域值所占空间很小,建议少使用压缩。
2.2.3 其他
项向量
Reader、TokenStream和byte[]域值及Field对象初始化[1]P42
域排序选项[1]P44
多值域[1]P44,使用相同域名,而加入多个域值。要注意若要分开内容查询,则需要重载设置域值之间的间隔。
2.3 加权操作
文档加权操作doc.setBoost(float) 域加权操作field.setBoost(float)
当改变加权因子时,必须完全删除并创建对应的文档,或使用updateDocument方法达到同样的效果。
2.3.1加权基准(Norms)
详见[1]P47,其面临的问题之一就是搜索期间的高内存用量。关闭norms相关操作,NO_NORMS选项或Field.setOmitNorms(true)
如果在索引进行一半时关闭norms选项,那么你必须对整个索引进 行重建,因为即使只有一个文档域在索引时包含了 norms选项,那么在随后的段合并操 作中,这个情况会“扩散”,从而使得所有文档都会占用一个字节的norms空间,即使 它们在此前的索引操作中关闭了 norms选项也是如此。发生这种情况主要是因为Lucene 并不针对norms进行松散存储。
2.4索引数字、时间与日期
详见[1]2.6节
2.4 索引截取
建立IndexWriter时 ,MaxFieldLength.UNLIMITED 不采取截取策略 MaxFieldLength.LIMITED只截取域中前1000个项。
建立IndexWriter后,使用setMaxFieldLength方法,getMaxFieldLength方法获得当前截取限制。该调用不具有追溯效果。
2.5近实时搜索、优化索引
IndexReader getReader()能实时刷新缓冲区中新增或删除的文档。该方法的调用会降低索引效率。
优化索引就是讲索引多个段合并成一个或少量段,从而减少对多段索引搜索后合并的操作。详见[1]P52,索引优化的doWait选项可以立即返回并在后台线程执行优化。
2.6 Directory
静态的 FSDirectory.open方法。该方法会根据当前的操作系统和平台来尝试选择最合适的默 认FSDirectory子类。
可以按照类似如下的方式将另一个Directory中的内容拷贝到 RAMDirectory 中: Directory ramDir = new RAMDirectory(otherDir);
该方法通常用于针对现有的存在于磁盘上的索引进行搜索提速,它要求索引尺寸足够小。但当代操作系统能对当前使用的数据保存在i/o缓存,所以该方法可能不会对产 生太大的性能提升。