Lucene系列-FieldCache
域缓存,加载所有文档中某个特定域的值到内存,便于随机存取该域值。
用途及使用场景
当用户需要访问各文档中某个域的值时,IndexSearcher.doc(docId)获得Document的所有域值,但访问速度比较慢,而且只能获得Stored域的值。
FieldCache能获得域值数组,根据docId random access域值。FieldCache是高级内部API,通常用户不会直接使用,Lucene的域值排序、过滤等功能会在内部使用域缓存。
原理
域缓存构造过程:
un-invert倒排索引,从(field value -> doc)数据结构转化得到(doc -> field value)数据结构,获得域值数组。
Lucene提供了如下方式显示获取域缓存:
/**
* reader 对应一个段(segment)的索引reader
* field 域名
* setDocsWithField true会获得一个bitset标记一个文档是否有该field
*/
FieldCache.Ints FieldCache.DEFAULT.getInts(AtomicReader reader, String field, boolean setDocsWithField)
对于给定的reader和域进行首次域缓存访问时,程序访问所有文档值并以一维大数组的形式加载到内存,用weakhashmap管理,key为reader实例和域名,value为域值数组。每当reader实例被关闭或被没有引用时,对应的缓存会被清除。首次访问后、被清除前的调用都会返回相同数组的引用。
域缓存有2个不足:
1. 常驻内存,大小是所有文档个数 * 值类型大小
2. 初始加载过程耗时,需要遍历倒排索引及类型转换
注意点:
1. 域值要单一,对于string类型不能分词(NOT_ANALYZED)
2. 该域需要建入索引(INDEXED)
3. 支持的数据类型,byte/short/int/long/float/double
改进:
Lucene针对FieldCache的不足进行了改进,在建索引的时候生成了doc -> field value数据结构,无需全驻内存和遍历解析。实现依赖于DocValues,域类型设为DocValues格式,在加载FieldCache时,程序会先尝试获取DocValues,获取失败才会开始遍历倒排索引。对于DocValues再另起文章介绍。
final NumericDocValues valuesIn = reader.getNumericDocValues(field);
if (valuesIn != null) {
// Not cached here by FieldCacheImpl (cached instead
// per-thread by SegmentReader):
return new Ints() {
@Override
public int get(int docID) {
return (int) valuesIn.get(docID);
}
};
一些API
基于lucene 4.10.0
//获取Int
FieldCache.Ints ints = FieldCache.DEFAULT.getInts(AtomicReader reader, String field, boolean setDocsWithField)
//获取docId的域值
int value = ints.get(docId)
//获取string
BinaryDocValues terms = getTerms(AtomicReader reader, String field, boolean setDocsWithField)
String value = terms.get(docId).utf8ToString()
//基于FieldCache的Filter
Filter f = FieldCacheRangeFilter.newIntRange("left", 0, 100, true, true);
Filter filter = new FieldCacheTermsFilter("type",
new BytesRef[]{new BytesRef("science"), new BytesRef("it")});
参考
http://blog.trifork.com/2011/10/27/introducing-lucene-index-doc-values/
Lucene系列-FieldCache的更多相关文章
- [lucene系列笔记1]lucene6的安装与配置(Windows系统)
lucene是一个java开源的高效全文检索工具包,最近做项目要用到,把学习的过程记录一下. 第一步:下载安装jdk 1.首先从官网下载jdk(下载之前先查看你的电脑是多少位操作系统,如果是32就下载 ...
- Lucene系列-索引文件
本文介绍下lucene生成的索引有哪些文件组成,每个文件包含了什么信息.基于Lucene 4.10.0. 数据结构 索引(index)包含了存储的文档(document)正排.倒排信息,用于文本搜索. ...
- Lucene系列-近实时搜索(1)
近实时搜索(near-real-time)可以搜索IndexWriter还未commit的内容,介于immediate和eventual之间,在数据比较大.更新较频繁的情况下使用.本文主要来介绍下如何 ...
- Lucene系列-facet
1.facet的直观认识 facet:面.切面.方面.个人理解就是维度,在满足query的前提下,观察结果在各维度上的分布(一个维度下各子类的数目). 如jd上搜“手机”,得到4009个商品.其中品牌 ...
- Lucene系列-搜索
Lucene搜索的时候就要构造查询语句,本篇就介绍下各种Query.IndexSearcher是搜索主类,提供的常用查询接口有: TopDocs search(Query query, int n); ...
- Lucene系列-分析器
分析器介绍 搜索的基础是对文本信息进行分析,Lucene的分析工具在org.apache.lucene.analysis包中.分析器负责对文本进行分词.语言处理得到词条,建索引和搜索的时候都需要用到分 ...
- Lucene系列-概述
为了生存,就得干一行爱一行.那就学习下lucene吧. 全文检索介绍 流程: 建索引 准备待搜索文档 文档分词:将文档分成一个个单独的单词,去除标点符号.停词(无意义的冠词介词等),得到token 语 ...
- Lucene系列六:Lucene搜索详解(Lucene搜索流程详解、搜索核心API详解、基本查询详解、QueryParser详解)
一.搜索流程详解 1. 先看一下Lucene的架构图 由图可知搜索的过程如下: 用户输入搜索的关键字.对关键字进行分词.根据分词结果去索引库里面找到对应的文章id.根据文章id找到对应的文章 2. L ...
- Lucene系列五:Lucene索引详解(IndexWriter详解、Document详解、索引更新)
一.IndexWriter详解 问题1:索引创建过程完成什么事? 分词.存储到反向索引中 1. 回顾Lucene架构图: 介绍我们编写的应用程序要完成数据的收集,再将数据以document的形式用lu ...
随机推荐
- [原创] Go语言在Centos上的部署
序言 Golang是个好东西啊.部署非常简单,对于运维人员来说太爽了. 传统的Nginx啊Apache啊,外加PHP以及各个插件啊搞得头晕. 用了Go之后就什么都不需要了.只要把生成好的文件向服务器上 ...
- CSS3属性box-sizing
1.box-sizing属性是CSS3的属性,有3个值:border-box.content-box.inherit. 2.默认是content-box,就是我们知道的width.padding.bo ...
- C#接口等基础知识
- linux 查找文件和搜索文件
按照文件名搜索 find . -name 'file name' grep -lr 'content' filepath
- iOS 图片文件格式判断、圆角图片
1.圆角图片 // 设置圆形图片(放到分类中使用) - (UIImage *)cutCircleImage { UIGraphicsBeginImageContextWithOptions(self. ...
- Kafka replication
Kafka replication kafka_replication_detailed_design_v2.pdf kafka Detailed Replication Design V3 Apac ...
- 【BZOJ】3997: [TJOI2015]组合数学
题意 \(N \times M\)的网格,一开始在\((1, 1)\)每次可以向下和向右走,每经过一个有数字的点最多能将数字减1,最终走到\((N, M)\).问至少要走多少次才能将数字全部变为\(0 ...
- Python几种常用的测试框架
一.测试的常用规则 一个测试单元必须关注一个很小的功能函数,证明它是正确的: 每个测试单元必须是完全独立的,必须能单独运行.这样意味着每一个测试方法必须重新加载数据,执行完毕后做一些清理工作.通常通过 ...
- 给li标签添加自定义属性
给li标签添加属性<ul> <li></li> <li></li> <li></li> <li>< ...
- List<T>Find方法,FindAll方法,Contains方法,Equals方法
假如传入的T是一个类, List<MessageInfos> MessageInfos = new List<MessageInfos>(); MessageInfos= Me ...