自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(163)
  • 资源 (3)
  • 收藏
  • 关注

原创 Lucene 7.5.0源码 博客计划

博客中的Lucene版本是7.5.0。博客中所有的文章是在本地写的,然后复制粘贴内容到网页,所以网页上的内容可能会有兼容问题,比如说单词之间没有空格。。。当然了,每篇文章都提供附件下载。如果你喜欢我的文章,强烈建议下载附件后阅读,然后用MarkDown软件查看,强烈推荐Typora(因为我在本地就是用这个软件写的,谁用谁知道)。博客中所有关于Lucene文章的代码大家可以在我的GitHub中找...

2019-01-23 17:47:12 220 2

原创 Lucene 查询TopN的优化(二)

在上一篇文章的结尾,我们总结了使用NumericDocValues优化查询TopN的原理:假设查询TopN的排序规则为按照正排值从小大小的顺序,即正排值越小,优先级越高。故在开启优化后,当收集器收到一个文档号,先根据文档号从正排索引中拿到正排值,在满足某些条件后,根据正排值,通过查询BKD树获取所有小于该正排值的文档集合,该文档集合用于生成一个新的迭代器。随后每次传入到收集器的文档号将会从新的迭代器中获取,达到所谓的skip non-competitive documents的效果。  上文的描述中,我

2021-07-01 17:30:06 641

原创 Lucene IndexOrDocValuesQuery

本篇文章介绍下Lucene中用于优化范围(数值类型point或者term类型)查询的Query:IndexOrDocValuesQuery。  我们先通过这篇BLOG(如果链接失效,可以查看附件中的PDF)来概述下为什么会设计IndexOrDocValuesQuery。求交集的问题  在文章多个MUST的Query的文档号合并中我们说到,执行一个由多个子Query组成,并且它们的关系为MUST的BooleanQuery时,其过程是先根据每个子Query获取一个有序的文档号集合,然后基于开销最小的

2021-07-01 17:28:04 478

原创 Lucene 文档号收集器DocIdSet

本篇文章将介绍Lucene中用于存储文档号的数据结构DocIdSet,该抽象类的具体实现有以下几种,我们将一一介绍。图1:  图1中,DocsWithFieldSet跟RoaringDocIdSet已经介绍过了。建议先看下文章RoaringDocIdSet,因为该实现中会使用到图1中的其他DocIdSet对象,有助于理解。  无论在索引阶段还是搜索阶段,都会用到DocIdSet来存储文档号。例如在索引阶段,使用DocsWithFieldSet收集正排信息对应的文档号、使用RoaringDoc

2021-06-23 17:07:22 409 1

原创 Lucene 查询TopN的优化(一)

在索引阶段,我们可以在每一篇文档中添加一条或多条DocValues信息(正排),使得在查询阶段,当收集器Collector收集到满足查询条件的文档号后,可以根据文档号找到对应的正排信息,并依据正排信息对查询结果进行排序。图1:  图1中添加了3篇文档,红框标注即正排信息,我们在查询条件中设置一个排序规则:图2:  在图2的排序规则下,返回的结果为:图3:查询TopN的性能(优化前)  基于目前Lucene的查询模块设计,整个查询过程可以按照获取迭代器和收集器处理文档的

2021-06-21 15:24:28 186

原创 Lucene 段的强制合并(二)

我们紧接文章ForceMerge(一),继续介绍剩余的内容,先给出强制合并的流程图:图1:是否存在可以合并的段?图2:当前流程点的内容对应为源码中IndexWriter类的updatePendingMerges(…)方法,如下所示:图3:如果用一句话描述该方法的用途,那就是:根据段的合并策略从上一个流程点(收集所有的段)收集的段集合中筛选出真正参与合并的段集合(段集合由一个或者多个OneMerge(见文章ForceMerge(一)的介绍)组成)。图3中,这个方法使用synchronized修饰

2021-06-03 15:10:33 262

原创 Lucene 段的强制合并(一)

在执行了flush、commit等方法后,Lucene会基于段的合并策略对索引目录中的段集合进行合并操作。Lucene在IndexWriter类中也提供了额外的方法允许用户可以主动去执行段的合并操作。ForceMerge概述  本篇文章将基于IndexWriter类中的下面两个方法来介绍下强制合并的内容。图1:图2:  在图1中的方法实际是另参数doWait为true,随后调用了图2中的方法。该参数的作用在下文中会展开。我们先通过源码中该方法的部分注释来描述下ForceMer

2021-05-27 11:26:02 432

原创 Lucene 内存索引(一)

从本篇文章开始介绍Lucene中提供的基于内存的搜索引擎的内容。我们通过MemoryIndex类的注释简单的了解下。图1:  图1中中包含了两个重点内容:单文档:使用MemoryIndex生成的索引是单文档(single-document)的,所有的索引数据都在同一篇文档中 使用场景:不适用于数量大并且需要持久化的数据场景;适用于数量较小、瞬时实时的数据、查询频繁的场景,在随后的文章中,我们会介绍MemoryIndex在Elasticsearch中的应用场景内存索引图2:  

2021-05-18 10:51:33 763

原创 Lucene 索引文件的载入(一)之fdx&&fdt&&fdm

在文章SegmentReader(一)中,我们介绍了SegmentReader对象,它用于描述一个段中的索引信息,并且说到SegmentReader对象中包含了一个SegmentCoreReaders对象。图1:  图1中,蓝框标注的两个对象用于描述DocValues的索引信息,而红框标注的SegmentCoreReader则描述了下面的索引信息,注意的是在文章SegmentReader(一)中是基于Lucene 7.5.0的:表一:对象 描述 StoredFieldsRead

2021-05-18 10:48:46 196

原创 Lucene SIMD(Single Instruction Multiple Data)

从Lucene 8.4.0开始,在写入/读取倒排信息时,即写入/读取索引文件.doc、.pos、.pay时,通过巧妙的编码方式(下文中展开)使得C2编译器能生成SIMD(Single Instruction Multiple Data)指令,从而提高了写入/读取速度。SIMD(Single Instruction Multiple Data)  下文中关于SIMD的介绍基于以下的一些资料,如果链接失效,可以阅读文章底部附件中的备份:文章一:http://www1.cs.columbia.edu/

2021-01-22 10:28:19 250

原创 Lucene 索引文件的合并(四)之kdd&kdi&kdm

本篇文章开始介绍索引文件kdd&kdi&kdm的合并,由于维度值为1和维度值大于等于2的点数据对应的索引文件的合并方式有较大的差异,故我们分开介绍。本篇文章先对维度值为1的情况展开介绍,建议先阅读文章索引文件的生成(二十五)之kdd&kdi&kdm,了解下维度值为1的点数据是如何生成索引文件的。索引文件kdd&kdi&kdm的合并流程图(维度值为1)图1:  图1中,流程点构建BKD树的节点元数据(node metadata)跟生成索引文件.d

2020-12-23 09:38:22 281

原创 Lucene 索引文件的生成(二十五)之kdd&kdi&kdm

在系列文章索引文件的生成(Lucene 7.5.0)中,我们介绍了存储维度(见文章Bkd-Tree)值大于等于2的数值类型对应的索引文件的生成过程。对于维度值等于1的情况,其生成过程有少许的不同。为了后续便于介绍该类型的索引文件的合并,我们需要再写一篇文章来介绍其生成过程。索引文件的变更图1:  从Lucene 8.6.0开始,用于存储点数据(point value)的索引文件由原先的索引文件dim&&dii,改为三个索引文件kdd&kdi&kdm,其变更的目

2020-12-18 16:02:24 311 1

原创 Lucene ReaderPool(二)

本文承接文章ReaderPool(一),继续介绍剩余的内容。读取ReaderPool对象  我们继续介绍ReaderPool对象中的readerMap这个map容器ReaderAndUpdates中包含的实例变量。图1:图2:boolean isMerging图3:  正如图3中的注释描述的那样,isMerging这个布尔值相用来描述一个段是否正在参与段的合并操作。如果一个段正在合并中,并且该段中的有些文档满足DocValues的更新条件(更新方式见文章文档的增删改(

2020-12-09 14:15:57 77

原创 Lucene ReaderPool(一)

ReaderPool类对于理解Lucene的一些机制起到了极其关键的作用,这些机制至少包含段的合并、作用(apply)删除信息、NRT(near real-time)、flush/commit与merge的并发过程中的删除信息的处理等等,所以有必要单独用一篇文章来介绍这个类。下面先给出源码中对于这个类的介绍:图1:  图1的javadoc中这样描述ReaderPool类:该类持有一个或多个SegmentReader对象的引用,并且是shared SegmentReader,share描述的是在f

2020-12-09 14:15:14 103

原创 Lucene 索引文件的合并(三)之fdx&&fdt&&fdm

本文承接文章索引文件的合并(二)之fdx&&fdt&&fdm,继续介绍剩余的内容,下面先给出索引文件fdx&&fdt&&fdm的合并流程图。索引文件fdx&&fdt&&fdm的合并流程图图1:未配置IndexSort图2:  如果当前执行合并操作的IndexWriter中没有配置IndexSort,那么依次读取每一个待合并的段,依次读取段中的每篇文档的索引信息即可。回顾下在文章索引文件

2020-12-04 09:43:38 312

原创 Lucene 索引文件的合并(二)之fdx&&fdt&&fdm

本文承接文章索引文件的合并(一)之fdx&&fdt&&fdm,继续介绍剩余的内容,下面先给出索引文件fdx&&fdt&&fdm的合并流程图。索引文件fdx&&fdt&&fdm的合并流程图图1:DocMap[ ]数组  继续介绍图1的流程点之前,我们先介绍下DocMap[ ]数组,如果合并后的段是段内排序的,那么需要在构造MergeState(见文章索引文件的合并(一)之fdx&&amp

2020-12-02 19:23:59 201

原创 Lucene 索引文件的合并(一)之fdx&&fdt&&fdm

从本篇文章开始介绍索引文件合并的过程,其中合并策略、合并调度在之前的文章中已经介绍,没有阅读过这些文章并不会影响对本篇文章的理解。  由于本篇文章是索引文件的合并的开篇文章,故我们先给出各类索引文件合并的先后顺序,如下所示:图1:  图1中第96行的merge( )方法在被调用后,就开始依次对各种类型的索引文件进行合并,该方法被调用的时机点如下图所示:图2:  图2中的流程图是执行段的合并的完整流程,其介绍可以阅读系列文章执行段的合并。在红框标注的流程点执行索引文件的合并中会调用

2020-12-02 19:23:09 365

原创 Lucene 索引文件之tvd&&tvx&&tvm

在索引(Indexing)阶段,当某个域被设置为需要记录词向量(term vector)信息后,那么随后在flush阶段,该域对应的词向量将被写入到索引文件.tvd&&tvx&&tvm三个文件中。图1:  图1中,域名"content"跟"title"都被设置为需要记录词向量信息,而域名"author"则没有。数据结构索引文件.tvd图2:PackedIntsVersion  PackedIntsVersion描述了压缩使用的方式,当前版本

2020-11-17 18:21:03 339

原创 Lucene 索引文件的读取(十五)之fdx&&fdt&&fdm

本文承接文章索引文件的读取(十四)之fdx&&fdt&&fdm,继续介绍剩余的内容。为了更好的理解下文中的内容,建议先阅读文章DirectMonotonicWriter&&Reader。下面先给出读取索引文件fdx&&fdt&&fdm的流程图。读取索引文件fdx&&fdt&&fdm的流程图图1:读取一个Chunk图2:  当图1的流程点文档号是否在BlockState不

2020-11-17 18:19:52 207

原创 Lucene Changes (Lucene 8.7.0)

2020年11月3号,Lucene发布了最新的版本8.7.0,本篇文章将会对Change Log中几个变更展开介绍下。LUCENE-9510  该issue的原文如下:1Indexing with an index sort is now faster by not compressing temporary representations of the data.   上文大意为:当设置了段内排序IndexSort后,索引(Indexing)的速度比以前更快了,因为不再压缩临时的数据

2020-11-17 18:18:34 378

原创 Lucene 索引文件的读取(十四)之fdx&&fdt&&fdm

在前几篇索引文件的读取的系列文章中,我们介绍索引文件tim&&tip的读取时机点时说到,在生成StandardDirectoryReader对象期间,会生成SegmentReader对象,该对象中的StoredFieldsReader信息描述了索引文件fdx&&fdt&&fdm中所有域的索引信息,故我们从本篇文章开始介绍索引文件fdx&&fdt&&fdm的读取。StoredFieldsReader  在生成Standar

2020-11-02 17:20:32 857

原创 Lucene 索引文件之kdd&kdi&kdm

从Lucene8.6.0开始,用于存储点数据(point value)的索引文件由原先的两个索引文件dim&&dii,改为三个索引文件kdd&kdi&kdm。由于生成kdd&kdi&kdm的过程基本上没有太大的变动,并且索引文件的数据结构中的字段也变化不大。故本文不会再详细介绍每一个字段的含义,即阅读本章前,最好先看下文章索引文件dim&&dii的数据结构,以及索引文件dim&&dii的生成过程以及索引文件dim&&am

2020-10-27 14:10:55 639

原创 Lucene 索引文件的生成(二十三)之fdx&&fdt&&fdm

从本篇文章开始介绍用于描述存储域(存储域的概念见文章索引文件之fdx&&fdt&&fdm)的索引文件.fdx、.fdt、.fdm的生成过程,直接给出流程图:图1:  从图1中可以看出,生成完整的索引文件.fdx、.fdt、.fdm的过程分布在两个阶段:索引阶段、flush阶段。这也解释了为什么在文章文档提交之flush(三)的图5中,其他索引文件都是"生成"、而索引文件.fdx、.fdt、.fdm则是"更新",注意的是那篇文章中是基于Lucene 7.5.0,故不

2020-10-15 00:33:17 373

原创 Lucene FST算法(二)

在文章FST(一)(必须先阅读该篇文章)中我们通过一个例子,简单的描述了Lucene是如何使用一个字节数组current[]存储FST信息的,为了能更好的理解读取过程,我们需要另外给出例子(差别在于把"mop"改成了"mo"),输入数据以及对应FST的信息如下String[] inputValues = {"mo", "moth", "pop", "star", "stop", "top"};long[] outputValues = {100, 91, 72, 83, 54, 55};图1:.

2020-10-09 19:42:04 437

原创 Lucene FST算法

FST(Finite State Transducer)算法的概念在这篇博客中并不涉及,网上有太多的资料啦,写的都非常的不错。这里推荐这位网友的介绍:https://www.shenyanchao.cn/blog/2018/12/04/lucene-fst/。如果链接失效了,可以看附件中的副本。本文中,我们基于一个例子来介绍在Lucene中如何构建FST。感谢网友关新全的分享,基于他的分享使得我在看源码的时候事半功倍,在此基础上,增加一些更加贴近源码的内容。同样的,关新全同学分享的文章在附件中。准备工.

2020-09-22 18:05:12 724

原创 Lucene 索引文件的读取(十三)之doc&&pos&&pay

本文承接文章索引文件的读取(十二)之doc&&pos&&pay,继续介绍剩余的内容。索引文件.doc、.pos、.pay的读取过程相比索引文件.tim&&.tip较为简单,核心部分为如何通过读取这三个索引文件,生成一个PostingsEnum对象,该对象中描述了term在一篇文档中的词频frequency、位置position、在文档中的偏移offset、负载payload以及该文档的文档号docId,其中docId和frequency通过索引文件.doc获得

2020-09-11 15:28:17 374

原创 Lucene 索引文件的读取(十二)之doc&&pos&&pay

在前几篇索引文件的读取的系列文章中,我们介绍索引文件tim&&tip的读取时机点时说到,在生成StandardDirectoryReader对象期间,会生成SegmentReader对象,该对象中的FieldsProducer信息描述了索引文件tim&&tip、索引文件doc、索引文件pos&&pay中所有域的索引信息,故我们从本篇文章开始介绍索引文件.doc、.pos、.pay的读取。索引文件.doc的数据结构(Lucene 8.4.0)  在文章索

2020-09-11 15:27:18 219

原创 Lucene 索引文件的生成(二十二)之nvd&&nvm

在执行flush()的过程中,Lucene会将内存中的索引信息生成索引文件,本篇文章继续介绍索引文件.nvd&&.nvm,其生成的时机点如下图红色框标注:图1:  图1的流程图属于Lucene 7.5.0,在Lucene 8.4.0中同样适用,该流程图为flush()过程中的一个流程点,详情见文章文档提交之flush(二)。  生成索引文件.nvd&&.nvm的目的在于存储normValue值以及文档号,我们先了解下在索引阶段(index phase),Luc

2020-08-28 15:48:58 343

原创 Lucene Automaton(三)

在文章Automaton(二)中我们根据图1的例子生成了图2的转移图以及转移图对应在源码中的描述方式,即状态(state)、转移(transition)函数两个数组,如图3所示:图1:图2:图3:  如果给定一个term,它的最后一个字符作为输入字符,随后在某个状态下,能根据某个转移函数找到下一个状态,并且该状态为可接受状态,那么term是被DFA接受的,其中输入字符、状态、转移函数、DFA的概念见文章Automaton的介绍。  根据图3的两个数据结构,用肉眼已经可以判断出

2020-08-24 09:47:36 140

原创 Lucene 索引文件的读取(十一)之tim&&tip

 在上一篇文章索引文件的读取(十)之tim&&tip中我们遗留了一个问题:  为什么要根据是否达到阈值使用不同的处理方式:  这个问题可以分解为两个小问题:问题一:为什么达到阈值后不使用BooleanQuery的方式做文档号的收集 问题二:为什么未达到阈值使用BooleanQuery的方式做文档号的收集处理方式  这两种处理方式的不同之处就在于如何根据每个term对应的文档号集合,并从这些集合中获取满足查询条件的文档号集合。未达到阈值  未达到阈值的情况下,会根据

2020-08-19 17:40:02 168

原创 Lucene 索引文件的读取(十)之tim&&tip

本文承接文章索引文件的读取(九)之tim&&tip,继续介绍剩余的流程点,先给出流程图:获取满足TermRangeQuery查询条件的term集合的流程图图1:收集Term图2:  在文章索引文件的读取(九)之tim&&tip中我们说到,在查询期间,满足查询条件的term数量未达到阈值(默认值16)跟达到阈值后的处理方式是不同的。未达到阈值  当满足查询条件的term数量未达到阈值(默认值16),会将TermRangeQuery转变为Boo

2020-08-12 18:51:27 247

原创 Lucene 索引文件的读取(九)之tim&&tip

 本文承接文章索引文件的读取(八)之tim&&tip,继续介绍剩余的流程点,先给出流程图:获取满足TermRangeQuery查询条件的term集合的流程图图1:获取迭代器IntersectTermsEnum图2:  IntersectTermsEnum类继承于抽象类TermsEnum,TermsEnum在Lucene中到处可见,它封装了一个段中term的相关操作,下面罗列了TermsEnum类中的几个常用/常见的方法:TermsEnum判断段中是否存在某

2020-08-10 18:38:30 292

原创 Lucene 索引文件的读取(八)之tim&&tip

本文承接文章索引文件的读取(七)之tim&&tip,继续介绍剩余的流程点,先给出流程图:获取满足TermRangeQuery查询条件的term集合的流程图图1:BlockTreeTermsReader  在上一篇文章中,我们已经介绍了当前流程点BlockTreeTermsReader,并且提到在生成FieldReader期间,会采用on-heap/off-heap两种导入模式(loadMode)来获取所有域的FST的主要信息,但是没有说明Lucene是如何选择这两种导入模

2020-08-05 15:26:48 476

原创 Lucene 索引文件的读取(七)之tim&&tip

本篇文章开始介绍索引文件tim&&tip的读取,通过TermRangeQuery的例子来介绍如何从索引文件.tim&&.tip中获取满足查询条件的所有term。  为了便于介绍,使用了文章Automaton(二)中提供的例子:图1:  结合图1的例子,获取满足查询条件(第79行代码)的所有term的过程可以简单的用一句话来描述:根据域名"content",从索引文件.tim&&.tip中获取该域对应的term集合,随后遍历集合中的每一个term

2020-08-04 19:31:35 536

原创 Lucene Automaton(二)

 在文章Automaton中我们介绍了确定型有穷自动机(Deterministic Finite Automaton)的概念,以及在TermRangeQuery中如何根据查询条件生成一个转移图,本文依旧根据该文章中的例子,介绍在Lucene中如何构建DFA,即生成图2的转移图,以及存储状态(state)、转移(transition)函数的数据结构。  我们再次给出文章Automaton中的例子:图1:  图1的第79行代码描述了TermRangQuery的查询范围为["bc","gch"],

2020-07-27 19:53:00 290

原创 Lucene 范围域 RangeField(一)

本文将介绍Lucene中提供的范围域(RangeField),以及基于该域实现的范围查询。范围域(RangeField)  RangeField使得一个域有了空间的概念,并且最多支持到四维(4 dimensions):1 dimensions:该维度的域描述了一条直线上的一段长度,如果有如下的定义:图1:  用图形来描述这个域的话如下所示:图2:2 dimensions:该维度的域描述了平面上的一个矩形,如果有如下的定义:图3:  用图形来描述这个域的话如下所示:

2020-07-23 11:32:11 317

原创 Lucene 索引文件的读取(六)

本文接着介绍索引文件.dvd、.dvm之BinaryDocValues的读取,它同SortedValues一样,其中一个用途用于对查询结果的进行排序,在搜索阶段,当获取了满足查询条件的文档号之后,它会交给Collector实现收集功能,并且在收集过程中实现文档的排序,我们通过一个例子来介绍如何实现排序。看这里:https://www.amazingkoala.com.cn/Lucene/Search/2020/0715/155.html...

2020-07-15 16:51:19 241

原创 Lucene 索引文件的读取(五)

本篇文章开始介绍索引文件.dvm&&dvd的读取,阅读本系列文章建议先看下文章索引文件的生成(十八)之dvm&&dvd、索引文件的生成(十九)之dvm&&dvd、IndexedDISI(一)、IndexedDISI(二),了解写入的过程能快的理解读取的逻辑。  DocValues的其中一个用途用于对查询结果的进行排序,在搜索阶段,当获取了满足查询条件的文档号之后,它会交给Collector实现收集功能,并且在收集过程中实现文档的排序。本文先介绍在使用Sor

2020-07-15 16:50:20 258

原创 Lucene 软删除 softDeletes(六)

我们接着文章软删除softDeletes(五)继续介绍合并策略SoftDeletesRetentionMergePolicy,在文章近实时搜索NRT(一)中使用方法三&&方法四获取StandardDirectoryReader和文章文档提交之flush(八)终中执行流程点更新ReaderPool的流程图时,会判断一个段中的文档是否都被删除(软删除跟硬删除),如果为真,那么这个段对应的索引文件,也就是索引信息将从索引目录中物理删除(如果没有其他reader占用的话),但是如果使用了合并策略So

2020-07-09 18:43:48 175

原创 Lucene 软删除 softDeletes(五)

在文章软删除softDeletes(二)中介绍了软删除在索引(index)阶段的相关内容,我们接着介绍在flush/commit阶段的内容flush/commit  在这个阶段,我们首先要介绍的是DWPT在转化为一个段的期间,即下图中用红框标注的流程点,跟软删除相关的内容:图1:点击查看大图  上图中,流程点将DWPT中收集的索引信息生成一个段newSegment的介绍见文章文档提交之flush(三),注意的是,图1中的流程点基于版本为Lucene 7.5.0,但是软删除相关的处理时

2020-07-08 15:44:06 145

Lucene DocValues介绍

介绍了Lucene 7.5.0版本的 DocValues,文档中的链接包含了SortedSetDocValues、SortedDocValues、NumericDocValues、SortedNumericDocValues、BinaryDocValues

2019-04-22

ZooKeeper分布式过程协同技术

高清 书签 史上最高清的版本了吧 赶紧下载吧 同学们 嘻嘻

2018-09-27

effective STL 高清+标签

effective STL 高清+标签 复印版 不会有任何的错误 的

2018-05-16

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除