OpenBitSet和OpenBitSetIterator在TermRangeQuery中的运用
在MultiTermQuery 的rewrite方法中,如果 if (pendingTerms.size() >= termCountLimit || docVisitCount >= docCountCutoff) 的就会使用MultiTermQueryWrapperFilter,如果查询出来的term的总数目大于termCountLimit或者docVisitCount是 df ,如果df 大于docCountCutoff 则使用MultiTermQueryWrapperFilter,否则使用BooleanQuery,他们之间的关系是or的关系, MultiTermQueryWrapperFilter 使用OpenBitSet收集docId,使用OpenBitSetIterator还原docId
@Override
public Query rewrite(IndexReader reader, MultiTermQuery query) throws IOException {
// Get the enum and start visiting terms. If we
// exhaust the enum before hitting either of the
// cutoffs, we use ConstantBooleanQueryRewrite; else,
// ConstantFilterRewrite:
final Collection<Term> pendingTerms = new ArrayList<Term>();
final int docCountCutoff = (int) ((docCountPercent / 100.) * reader.maxDoc());
final int termCountLimit = Math.min(BooleanQuery.getMaxClauseCount(), termCountCutoff);
int docVisitCount = 0;
FilteredTermEnum enumerator = query.getEnum(reader);
try {
while(true) {
Term t = enumerator.term();
if (t != null) {
pendingTerms.add(t);
// Loading the TermInfo from the terms dict here
// should not be costly, because 1) the
// query/filter will load the TermInfo when it
// runs, and 2) the terms dict has a cache:
docVisitCount += reader.docFreq(t);
}
if (pendingTerms.size() >= termCountLimit || docVisitCount >= docCountCutoff) {
// Too many terms -- make a filter.
Query result = new ConstantScoreQuery(new MultiTermQueryWrapperFilter<MultiTermQuery>(query));
result.setBoost(query.getBoost());
return result;
} else if (!enumerator.next()) {
// Enumeration is done, and we hit a small
// enough number of terms & docs -- just make a
// BooleanQuery, now
BooleanQuery bq = new BooleanQuery(true);
for (final Term term: pendingTerms) {
TermQuery tq = new TermQuery(term);
bq.add(tq, BooleanClause.Occur.SHOULD);
}
// Strip scores
Query result = new ConstantScoreQuery(new QueryWrapperFilter(bq));
result.setBoost(query.getBoost());
query.incTotalNumberOfTerms(pendingTerms.size());
return result;
}
}
} finally {
enumerator.close();
}
}
收集的docId的代码 调用如图所示
先new 一个OpenBitSet,大小是查询出来的当前segemt中最大文档的数目,然后通过
SegmentTermDocs 的public int read(final int[] docs, final int[] freqs)
这个方法读取docId和frg,然后 通过for循环
for(int i=0;i<count;i++) {
bitSet.set(docs[i]);
}
把docId放到OpenBitSet里面
代码如下和注释如下
public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
//返回TermRangeTermEnum对象,这个对象先用用小的那个string new一个term,然后定位到tis文件,while循环读取term信息,然后去frg文件里面读取docId,在while循环里面,通过SegmentTermDocs读取frg文件的docId和frg。
final TermEnum enumerator = query.getEnum(reader);
try {
// if current term in enum is null, the enum is empty -> shortcut
if (enumerator.term() == null)
return DocIdSet.EMPTY_DOCIDSET;
// else fill into a OpenBitSet
final OpenBitSet bitSet = new OpenBitSet(reader.maxDoc());
final int[] docs = new int[32];
final int[] freqs = new int[32];
// new 一个SegmentTermDocs的实例,会调用它的read方法读取docId
TermDocs termDocs = reader.termDocs();
try {
int termCount = 0;
do {
Term term = enumerator.term();
if (term == null)
break;
termCount++;
SegmentTermDocs 在frg文件里面seek到term的对应的docid的开始位置
termDocs.seek(term);
while (true) {
// 读取docId,一次读取到32 个docId到 docs数组里面,如果没有32个则读取实际的数目
final int count = termDocs.read(docs, freqs);
if (count != 0) {
for(int i=0;i<count;i++) {
bitSet.set(docs[i]);
}
} else {
break;
}
}
} while (enumerator.next());
query.incTotalNumberOfTerms(termCount);
} finally {
termDocs.close();
}
return bitSet;
} finally {
enumerator.close();
}
}
enumerator.next()方法截图如下,enumerator是TermRangeTermEnum,会调用父类的FilteredTermEnum next方法。
FilteredTermEnum的next方法如下,他会调用actualEnum读取tis文件里面的下一个term,然后调用termCompare 方法,termCompare 这个方法是抽象方法,留给子类实现,
TermRangeTermEnum方法的实现逻辑是和右边的区间的term做一个比较,看查询的term是否超出区间
public boolean next() throws IOException {
if (actualEnum == null) return false; // the actual enumerator is not initialized!
currentTerm = null;
while (currentTerm == null) {
if (endEnum()) return false;
if (actualEnum.next()) {
Term term = actualEnum.term();
if (termCompare(term)) {
currentTerm = term;
return true;
}
}
else return false;
}
currentTerm = null;
return false;
}
还原是在ConstantScorer的nextDoc方法调用的如下图
public int nextDoc() throws IOException {
return docIdSetIterator.nextDoc();
}
- 大小: 34.1 KB
- 大小: 41.4 KB
- 大小: 9.7 KB
- 大小: 37.8 KB
- 大小: 32.2 KB
分享到:
相关推荐
我们可以使用OpenBitSet来缓存删除的文档,然后在FilterIndexReader中对其进行过滤。 索引更新是Lucene中的一种重要机制,用于实时更新索引中的文档。我们需要根据实际情况选择合适的删除方式,并使用...
例如,可以创建一个自定义的`MyFilterIndexReader`,它保存一个位集(`OpenBitSet`)来记录已被删除的文档,并在`numDocs()`等方法中调整结果以排除这些文档。 ```java public class MyFilterIndexReader extends...
源头 - 分布式位图索引原语 注意:该项目目前作为概念证明存在。 虽然我信任索引器,但仍有大量性能和... 我已经从非常出色的OpenBitSet (从 Lucene 复制)和一个包装了byte[]数组的简单位图构建了参考位图。源头哈
修炼成Javascript中级程序员必知必会_资源分享
内容概要:本文详细介绍了如何使用MATLAB的深度学习工具箱,在果树病虫害识别任务中从数据准备、模型设计、训练优化到最后的模型评估与应用全流程的具体实施步骤和技术要点。涵盖了MATLAB深度学习工具箱的基本概念及其提供的多种功能组件,如卷积神经网络(CNN)的应用实例。此外,文中还具体讲述了数据集的收集与预处理方法、不同类型的深度学习模型搭建、训练过程中的超参数设定及其优化手段,并提供了病虫害识别的实际案例。最后展望了深度学习技术在未来农业领域的潜在影响力和发展前景。 适合人群:对深度学习及农业应用感兴趣的科研人员、高校师生和相关从业者。 使用场景及目标:①希望掌握MATLAB环境下构建深度学习模型的方法和技术细节;②从事果树病虫害管理研究或实践,寻找高效的自动化解决方案。 阅读建议:在阅读本文之前,建议读者熟悉基本的MATLAB编程环境及初步了解机器学习的相关概念。针对文中涉及的理论和技术难点,可以通过官方文档或其他教程进行补充学习。同时,建议动手实践每一个关键点的内容,在实践中加深理解和掌握技能。
nodejs010-nodejs-block-stream-0.0.7-1.el6.centos.alt.noarch.rpm
机械模型与技术交底书的融合:创新点详解与解析,机械模型加技术交底书,有创新点 ,机械模型; 技术交底书; 创新点,创新机械模型与技术交底书详解
免费JAVA毕业设计 2024成品源码+论文+数据库+启动教程 启动教程:https://www.bilibili.com/video/BV1SzbFe7EGZ 项目讲解视频:https://www.bilibili.com/video/BV1Tb421n72S 二次开发教程:https://www.bilibili.com/video/BV18i421i7Dx
免费JAVA毕业设计 2024成品源码+论文+数据库+启动教程 启动教程:https://www.bilibili.com/video/BV1SzbFe7EGZ 项目讲解视频:https://www.bilibili.com/video/BV1Tb421n72S 二次开发教程:https://www.bilibili.com/video/BV18i421i7Dx
nodejs010-nodejs-cmd-shim-1.1.0-4.1.el6.centos.alt.noarch.rpm
西门子四轴卧加后处理系统:828D至840D兼容,四轴联动高效加工解决方案,支持图档处理及试看程序。,西门子四轴卧加后处理,支持828D~840D系统,支持四轴联动,可制制,看清楚联系,可提供图档处理试看程序 ,核心关键词:西门子四轴卧加后处理; 828D~840D系统支持; 四轴联动; 制程; 联系; 图档处理试看程序。,西门子四轴卧加后处理程序,支持多种系统与四轴联动
基于黏菌优化算法(SMA)的改进与复现——融合EO算法更新策略的ESMA项目报告,黏菌优化算法(SMA)复现(融合EO算法改进更新策略)——ESMA。 复现内容包括:改进算法实现、23个基准测试函数、多次实验运行并计算均值标准差等统计量、与SMA对比等。 程序基本上每一步都有注释,非常易懂,代码质量极高,便于新手学习和理解。 ,SMA复现;EO算法改进;算法实现;基准测试函数;实验运行;统计量;SMA对比;程序注释;代码质量;学习理解。,标题:ESMA算法复现:黏菌优化与EO算法融合改进的实证研究
基于MATLAB的Stewart平台并联机器人仿真技术研究与实现:Simscape环境下的虚拟模拟分析与应用,MATLAB并联机器人Stewart平台仿真simscape ,MATLAB; 并联机器人; Stewart平台; 仿真; Simscape; 关键技术。,MATLAB中Stewart平台并联机器人Simscape仿真
Grad-CAM可视化医学3D影像
探索comsol泰勒锥:电流体动力学的微观世界之旅,comsol泰勒锥、电流体动力学 ,comsol泰勒锥; 电流体动力学; 锥形结构; 电场影响,COMSOL泰勒锥与电流体动力学研究
免费JAVA毕业设计 2024成品源码+论文+数据库+启动教程 启动教程:https://www.bilibili.com/video/BV1SzbFe7EGZ 项目讲解视频:https://www.bilibili.com/video/BV1Tb421n72S 二次开发教程:https://www.bilibili.com/video/BV18i421i7Dx
PFC6.03D模型动态压缩模拟与SHPB霍普金森压杆系统理论及实验数据处理技术解析,PFC6.03D模型,动态压缩模拟,还包括: SHPB霍普金森压杆系统理论知识介绍,二波法和三波法处理实验数据,提出三波波形,计算动态压缩强度等 ,PFC模型; 动态压缩模拟; SHPB霍普金森压杆系统; 理论介绍; 二波法处理; 三波法处理; 三波波形; 动态压缩强度。,"PFC模型下的动态压缩模拟及SHPB理论实践研究"
ProASCI 开发板原理图,适用于A3P3000
免费JAVA毕业设计 2024成品源码+论文+录屏+启动教程 启动教程:https://www.bilibili.com/video/BV1SzbFe7EGZ 项目讲解视频:https://www.bilibili.com/video/BV1Tb421n72S 二次开发教程:https://www.bilibili.com/video/BV18i421i7Dx
1、文件内容:pykde4-devel-4.10.5-6.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/pykde4-devel-4.10.5-6.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、安装指导:私信博主,全程指导安装