根本原因
个人感觉,lucene的倒排索引的文档列表,之所以没有选择bitmap,并不是因为bitmap和跳表本身的性能差异,而是因为跳表除了能保存文档列表之外,还能保存其他信息,就比如说该term在文档中出现的次数
因为lucene是为全文检索而生的,全文检索非常关键的一点就是文档的相关度,其中非常重要的一点又是词项出现的频次,一个词项出现在三个文档中,第一个文档出现了3次,剩下两个文档中只出现了1次,那么第一个文档的相关度更高。
所以,如果查出term对应的文档列表之后,能顺便将该term在每个文档中出现的频次顺带拿到,那么后续评分将会非常方便。
对于这点来说,跳表实现起来方便多了,跳表最底层的链表的元素可以携带任意格式的信息;但是bitmap只能保存文档id,如果想要找term出现的次数,还需要再去另一个地方去查询,显然没有那么方便。
倒排索引与评分
倒排索引文件
1 | 12K Oct 10 17:25 _b_Lucene50_0.tip |
其中doc保存的是文档列表以及term在每个文档中出现的频率
可见文档列表文件中除了保存文档id之外,还需要保存term出现的次数。所以用bitmap来作为doc文件的数据结构是不合适的。
评分
评分的时候需要用到上面存储的:
- doc中的频次
- nvm和nvd中的字段长度和提升因子
畅享
lucene基于全文检索的需求,文档列表采用了跳表而不是bitmap,但是如果es的使用场景是olap分析,不存在评分,只是过滤查询,那么是不是文档列表使用bitmap更合适,因为bitmap拥有天然的做合并的优势。
druid是一个典型的olap分析引擎,他的维度列的倒排索引的使用的就是bitmap。
上面提到对于keyword字段来说,是只保存docs的,也就是文档列表对应的链表中只有文档id信息,那么这个时候,是不是用bitmap来存储更合适呢?
感觉应该是,因为es在lucene之上,对于filter类型的查询结果对应的文档列表是用bitmap缓存在内存中的,用于后续的多条件查询的时候进行合并,可见bitmap还是有优势的