lucene中的docValue实现源码解读(一)——综述

阅读更多

        docValue是一个很好用的东西,他是存储的正向的信息,即一个doc-->该doc的一个值,他是区别于stored的域的。在lucene中,docValue是按照列进行存储的,即所有的doc的某个相同名字的域存储在一起,而不是一个doc的所有的域的doc值存放在一起,这样做的好处是在使用lucnee中经常会按照域进行使用,比如我们在对做facet、sort的时候我们可能会使用到所有的doc的某个域的值,因此按照列进行存储可以将硬盘上的某个块加载到内存中,实现快速的读取某个域下所有的doc的docValue。而在lucene中,存储的域是按照doc进行的,即在写存储的域的时候,会先把一个doc所有的域都写在一起,然后才再写下一个doc的存储的域,这个特性适合于获得一个doc的很多的存储域,而不适合域查找多个doc的某一个域。所以当我们在做facet、sort的时候,是不可以使用存储域的,倒不是说不行,而是他的实现方式导致了效率很低下。而在lucene4.x中引入的docValue却更加适合这个功能。

        问题是,在3.x的时候没有docValue,那么lucene是如何做sort、facet的呢?答案很简单,使用的是词典表。在lucene4.x中,如果对一个域不建立docValue,也是可以做sort、facet的,他的实现原理和之前的一样,都是把整个域的所有的term从lucene词典表中读出来,然后再内存中做计算,找到每个doc对应的term,也就是找到正向信息。这样的效率是很低的,因为在打开一个段的时候,要把词典表读到内存中,做完计算后找到的正向信息还要保留在内存中,这是效率很差的。尤其是对于java这种内存回收比较差的语言来说(保留的地方就是lucene的FieldCache.DEFAULT中,是一个很大的map)。所以如果需要对一个域做facet、solr,使用docValue是一个更好的方式。docValue是不会使用到内存的(我说的是 jvm的内存,不是操作系统的虚拟内存),每个doc的docValue都是含有索引的,可以直接根据所以进行一次io即可获得一个doc的某个域的docValue,在某些类型的docValue中,在读取一个域的docValue的时候,会把整个部分的docValue的值都load到操作系统的内存中,这样在读取这些docValue的时候,就和在内存中一样了,能实现更高的效率。

       在lucene4.10.4中,有五种类型的docValue,这里我要把docValue的具体的存储和读取都看一遍,来看看lucene到底是怎么做的,以及我们在工作中应该如何使用docValue,以实现更高的效率。

 

 

你可能感兴趣的:(lucene,docValue,存储格式)