域缓存,加载所有文档中某个特定域的值到内存,便于随机存取该域值。

用途及使用场景

当用户需要访问各文档中某个域的值时,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的更多相关文章

  1. [lucene系列笔记1]lucene6的安装与配置(Windows系统)

    lucene是一个java开源的高效全文检索工具包,最近做项目要用到,把学习的过程记录一下. 第一步:下载安装jdk 1.首先从官网下载jdk(下载之前先查看你的电脑是多少位操作系统,如果是32就下载 ...

  2. Lucene系列-索引文件

    本文介绍下lucene生成的索引有哪些文件组成,每个文件包含了什么信息.基于Lucene 4.10.0. 数据结构 索引(index)包含了存储的文档(document)正排.倒排信息,用于文本搜索. ...

  3. Lucene系列-近实时搜索(1)

    近实时搜索(near-real-time)可以搜索IndexWriter还未commit的内容,介于immediate和eventual之间,在数据比较大.更新较频繁的情况下使用.本文主要来介绍下如何 ...

  4. Lucene系列-facet

    1.facet的直观认识 facet:面.切面.方面.个人理解就是维度,在满足query的前提下,观察结果在各维度上的分布(一个维度下各子类的数目). 如jd上搜“手机”,得到4009个商品.其中品牌 ...

  5. Lucene系列-搜索

    Lucene搜索的时候就要构造查询语句,本篇就介绍下各种Query.IndexSearcher是搜索主类,提供的常用查询接口有: TopDocs search(Query query, int n); ...

  6. Lucene系列-分析器

    分析器介绍 搜索的基础是对文本信息进行分析,Lucene的分析工具在org.apache.lucene.analysis包中.分析器负责对文本进行分词.语言处理得到词条,建索引和搜索的时候都需要用到分 ...

  7. Lucene系列-概述

    为了生存,就得干一行爱一行.那就学习下lucene吧. 全文检索介绍 流程: 建索引 准备待搜索文档 文档分词:将文档分成一个个单独的单词,去除标点符号.停词(无意义的冠词介词等),得到token 语 ...

  8. Lucene系列六:Lucene搜索详解(Lucene搜索流程详解、搜索核心API详解、基本查询详解、QueryParser详解)

    一.搜索流程详解 1. 先看一下Lucene的架构图 由图可知搜索的过程如下: 用户输入搜索的关键字.对关键字进行分词.根据分词结果去索引库里面找到对应的文章id.根据文章id找到对应的文章 2. L ...

  9. Lucene系列五:Lucene索引详解(IndexWriter详解、Document详解、索引更新)

    一.IndexWriter详解 问题1:索引创建过程完成什么事? 分词.存储到反向索引中 1. 回顾Lucene架构图: 介绍我们编写的应用程序要完成数据的收集,再将数据以document的形式用lu ...

随机推荐

  1. Tomat简介

    Tomcat目录结构bin: 存放各种平台下启动和关闭Tomcat的脚本文件.startup.bat是windows下启动tomcat的文件,shutdown.bat是关闭tomcat的文件.comm ...

  2. Redis——学习之路四(初识主从配置)

    首先我们配置一台master服务器,两台slave服务器.master服务器配置就是默认配置 端口为6379,添加就一个密码CeshiPassword,然后启动master服务器. 两台slave服务 ...

  3. POJ 1743 Musical Theme ——后缀数组

    [题目分析] 其实找最长的不重叠字串是很容易的,后缀数组+二分可以在nlogn的时间内解决. 但是转调是个棘手的事情. 其实只需要o(* ̄▽ ̄*)ブ差分就可以了. 背板题. [代码] #include ...

  4. Myeclipse运行报错:an out of memory error has occurred的解决方法

    不知道怎么了,重装的myeclipse2013,里边就放了一个项目,启动myeclipse就报 an out of memory error has occurred....... 一点yes就退出 ...

  5. WP8解析XML格式文件

    DOTA2 WebAPI请求返回的格式有两种,一种是XML,一种是JSON,默认是返回JSON格式,如果要返回XML格式的话,需要在加上format=xml. 这里举一个简单的解析XML格式的例子(更 ...

  6. 关于scale和zoom的区别

    其实关于scale,我之前是用他来搞一些css3的特效的放大缩小啊,玩的也挺6666,而*zoom:1之前是用来做css的hack,也就是触发IE6/7的haslayout清除浮动的.终于某天,好事的 ...

  7. Matlab读取数据中出现的问题

    在运行Matlab读取一段数据并做处理的时候,常常会提示服务器错误,但是等待一会再次运行就会成功运行. 代码如下: clc; clear all; [~,~,rawdata] = xlsread('进 ...

  8. Activemq mqtt 点对点聊天实现(转载)

    我这想到一个点对点聊天的方法,不用没割人都建立一个topic了,思路还是自定义一个分发策略,具体如下: 1.  建立一个topic,所有人都用匹配订阅的方式订阅以该topic为头的topic,例如:所 ...

  9. C#SerialPort如何读取串口数据并显示在TextBox上

    SerialPort中串口数据的读取与写入有较大的不同.由于串口不知道数据何时到达,因此有两种方法可以实现串口数据的读取.一.线程实时读串口:二.事件触发方式实现. 由于线程实时读串口的效率不是十分高 ...

  10. 深入浅出HTTP协议(WEB开发和面试必备)

    1. 基础概念篇   a.简介 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(World Wide Web Consortium)和 ...