Lucene在3.0提出了域缓存(FieldCache)的概念,这个API主要是在内部使用,但开发者也可以外部调用,在自定义排序或者自定义评分的时候都涉及到相关的接口。准确的说,就是将相关的域的值加载到内存中,形成一维数组。加载域缓存,并不要求相关域的值必须在索引中store,而是要求必须Index,并且不能分词,实际上域缓存的值是从倒排索引中转换而来。具体原理见下图
在lucene3.0中域缓存的API调用如下
针对字符域
FieldCache.DEFAULT.getStrings(reader, field);
针对数值域,比如Float类型
FieldCache.DEFAULT.getFloats(reader, field)
域缓存有两项不足
1. 常驻内存,大小是所有文档个数 * 值类型大小
2. 初始加载过程耗时,需要遍历倒排索引及类型转换
Lucene自4.0起提出了一个新的概念DocValue,允许用户在建索引的时候将相关域的文档id和域的value之间的影射直接保存在索引文件中。这也就意味着,用户需要在建立索引的时候,建立一种父类为DocValueField的特殊域,DocValueField有各种子域,关于DocValue,我们另写文章来谈。
因此,在lucene4.0中,Lucene在使用域缓存时,首先会去取对应的docValueField的值,然后再根据相关的doc id去随机获取域的值。如果docValueField并不存在,才会从倒排索引中进行类型转换,再加载到内存中,这是3.0中的机制。也就是说,默认会使用docValue代替域缓存。具体见代码
事实上,查了一下,在lucene6.0的API中,FieldCache已经被取消了。