lucene-新增,更新,删除过程解析

Lucene应用实战(一)——索引创建与搜索 Lucene简介 Lucene是非常优秀的成熟的开源的免费的纯java语言的全文索引检索工具包。 Lucene是一个高性能、可伸缩的信息搜索(IR)库。 Information Retrieval (IR) library.它可以为你的应用程序添加索引和搜索能力。 Lucene是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者 是以此为基础建立起完整的全文检索引擎。由Apache软件基金会支持和提供,Lucene提供了一个简单却强 大的应用程序接口,能够做全文索引和搜索。 阅读详情

lucene索引的核心流程

核心流程:新增,修改,删除,查询。
删除操作:没有什么特别的,内存中使用一个list对象记住将被删除的数据,调用commit数据最终才会被删除。
修改操作:先执行删除后新增的过程。

索引的基本流程

  1. 提取文本和创建文档:构建document实例和Field实例的过程
  2. 分析文档:将文本数据分割成词汇单串(看用的是什么解析器,不用的解析器会对英文的大小写,停词,以及中文的分词方式会有不同的处理)
  3. 向索引中新增文档:分析文档后,将分析结构以倒排索引的数据结构进行存储

新增索引

代码用例

    @Test
    public void addDoc() throws Exception {
        dir  = FSDirectory.open(Paths.get("/Users/siminglang/Desktop/Demo5"));
        IndexWriter indexWriter = getIndexWriter();
        for (int i = 0; i < ids.length; i++) {
            Document doc = new Document();
            doc.add(new StringField("id", ids[i], Field.Store.YES));
            doc.add(new StringField("city", citys[i], Field.Store.YES));
            doc.add(new TextField("desc", descs[i], Field.Store.NO));
            indexWriter.addDocument(doc);
        }
        indexWriter.close();
    }

基本流程:创建一个indexWriter类, 构建document实例,调用addDocument方法新增文档,调用indexWriter.close(方法内部会调用commit方法)提交文档

lucene新增索引的过程有何特点

  • 写入索引过程中会触发的操作:flush,commit,merge
  • lucene索引文档前,会判断是否需要进行段合并操作。 为什么要这样做,已经如何去实现它。
lucene的flush操作,实现了什么能力。又是怎么实现的

实现的能力:将缓存中的数据以segment的形式写入到磁盘当中。写入磁盘后,缓存会被释放。
如何实现:构建segmeng对象,写入到磁盘中。
在这里插入图片描述
在这里插入图片描述

lucene的commit又实现了什么能力呢?
  • commit提供的能力:让所有的更改,包括缓存中的更改或者已经刷新的能改在索引中保持可见。
  • 由lucene源码可知,commit的时候会执行flushAllThreads方法,对某个indexWriter所有的线程执行flush操作。
lucene数据写入过程流程图

在这里插入图片描述

lucene的merge操作

什么是merge操作:
段合并,如果索引中包含太多的段,IndexWriter会选择其中一些段并将它们合并成一个唯一的更大的段
好处:
加快搜索速度,因为被搜索的段的数量更少了;减少来索引的尺寸,例如如果被合并的段中包含删除操作的话,那么合并过程会释放文档删除标识所占用的数据位。即使没有删除操作,一般来说合并后的段也会占用更少的存储空间。
段合并时机:
变更操作进行刷新时;或者上一个段合并操作已经完成时
合并策略
段合并策略LogByteSizeMergePolicy,IndexWriter默认的情况下使用。该策略会测量段包含的所有文件的总字节数。
段合并策略LogDocMergePolicy,它测量的是段中的文档数量。
会按照段的尺寸对段进行分组,处于同一分组的段才可能被合并。每次合并时,只会取一个分组中的某些段进行合并,不会合并一个分组中的所有段,会控制参与合并的段的数量。maxMergeMB或者maxMergeDocs可以控制超过改数值的段不参与段合并,它们是大段。
控制段合并的类
MergePolicy来控制段合并
实施合并操作的类:MergerScheduler。它有两个子类,一个是ConcurrentMergeScheduler,后台线程完成段合并; 一个是SerialMergeScheduler,调用它的线程完成段合并。

删除索引

代码用例

    @Test
    public void deleteDoc() throws Exception {
        dir  = FSDirectory.open(Paths.get("/Users/siminglang/Desktop/Demo5"));
        IndexWriter indexWriter = getIndexWriter();
        indexWriter.deleteDocuments(new Term("id", "1"));
        indexWriter.commit();
        System.out.println("indexWriter.hasDeletions() :" + JSON.toJSONString(indexWriter.hasDeletions() ));
        System.out.println("indexWriter.getInfoStream() :" + JSON.toJSONString(indexWriter.getInfoStream()));
        System.out.println("indexWriter.getDocStats() :" + JSON.toJSONString(indexWriter.getDocStats()));
    }

基本流程:创建一个indexwriter对象;构建一个Term删除条件,匹配条件对的文档将会被删除;调用commit提交删除操作;

特性

  • 调用commit或者是close可以向索引中提交删除操作
  • 及时删除操作完成,存储文档的磁盘也不会立即被释放,lucene只是将文档标记为删除。真正的删除操作是在文档那对应的段进行合并时才执行
  • lucene中实现文档删除能力的类有两个:IndexReader和IndexWriter。IndexReader立即决定删除哪个文档。IndexWriter仅仅是将被删除的Term进行缓存,后续再进行实际的删除操作。
  • lucene使用一个简单的方式记录被删除的文档,使用bit数组的形式记录,这个操作速度非常快,但是被删除的文档数据依然占用文档空间。

更新文档

lucene更新文档的过程,其实是将文档删除后新增的过程。特性和流程和上述的类似。

lucene新增文档过程

疑问:

  • Field.Store字段的含义是?Store.YES 保存 可以查询 可以打印内容 ; Store.NO 不保存 可以查询 不可打印内容 由于不保存内容所以节省空间
  • 完成写入过程的类?DefaultIndexingChain.StoredFieldsConsumer完成字段的写入过程。
  • lucene是如何控制写入速度的?通过flushController进行控制,执行插入动作前,需要保证排队中的flush个数和停顿的线程数为0, 否则将执行flush操作。
  • 整理下DocumentsWriterFlushControl的能力

什么是lucene中的segment

  • lucene的索引是由一个或者多个segment组成的
  • 每个segment都是一个独立的索引,它是整个文档索引的一个子集
  • 每当write刷新缓冲区新增的文档,以及挂起目录删除操作时,索引文件都会建立一个新的段
  • 在搜索索引时,每个段都是单独访问的,但搜索结果是合并后返回的
  • 为了防止segment过多,影响搜索效率,lucene有segment合并策略,会周期性的将一些满足条件的segment合并成较大的segment。

何时回收被删除文档使用的磁盘空间

  • 发生段合并的时候
  • 显式调用optimize的时候,操作所有的段
  • expungeDeletes 只针对进行了删除操作的段进行合并

缓存和刷新

  • 为什么要用缓冲技术:减少磁盘IO
  • 当新增一个文档到lucene索引时,或者挂起一个删除操作时,这些操作首先会被刷到内存当中,而不是立即刷到磁盘中
  • 什么时候会触发将缓存中的数据刷新的磁盘当中呢?
    • 当缓存所占用的空间超过预设的RAM比例时进行刷新,预设方法为setRAMBufferSizeMB
    • 指定文档号对应的文档添加进索引后,通过调用setMaxBufferedDocs完成刷新
    • 在删除项和查询语句等操作占用的缓存总量超过预设值,可以通过调用setMaxBufferedDeleteTerm触发刷新操作。
    • 默认情况下,indexWriter只有在RAM用量为16M时启动刷新操作

索引提交

  • 索引提交后的可视性问题?
  • indexWriter的提交步骤:
  • 两阶段提交
  • 索引删除策略
    • IndexDeletionPolicy负责通知IndexWriter核实能够安全的删除旧的提交
    • 默认的KeepOnlyLastCommitDeletionPolicy, 该策略在每次创建完新的提交后删除先前的提交

如何提升索引文档的吞吐量

  • 常用方式:使用固态磁盘SSD;升级到最新的lucene版本;升级到最新的java版本;;indexWriter,indexReader,indexSearch尽量使用共享实例;使用多线程;尽量给lucene配置更多的内存
  • 尽可能的减少段的合并操作,因为该操作会消耗大量的CPU和IO资源
  • 调整indexWriter刷新事件的阈值,调用方法setRAMBufferSizeMB。通常来说缓冲值是越大越好,但是你需要通过测试来得到一个合适的实践值。
  • 关闭复杂文件格式选项,IndexWriter.setUseCompoundFile(false)
  • 对Document实例和Filed实例进行重用。
  • 针对不同的mergeFactor值进行测试,更高的值来带更低的索引开销,但同时也意味着更低的索引速度。但是一定要在真实的环境中进行测试。

并发,线程安全及锁机制

要点梳理

  • 任意数量的indexReader都可以同时打开同一个索引。但是需要记住,利用资源和发挥效率最好的方法是利用多线程共享一个indexReader实例。
  • 对于一个索引来说,一次只能打开一个Writer。lucene采用文件锁的方式来提供保障。一旦建立起来indexWriter对象,系统会立即分配一个锁给它。该锁只有当IndexWriter对像关闭时才释放。
  • 注意如果使用indexReader来改变索引的话,这时indexReader对象会作为writer使用,它必须在执行修改动作之前获取到锁,并在关闭时会释放掉锁。
  • indexReader 可以在indexWriter正在修改索引的时候打开。
  • indexReader对象只有在indexWriter对象提交修改或者自己重新打开后才能获知索引的修改情况??一个更好的选择,打开indexReader时采用的参数create=true。这样的话,indexReader会持续检查索引的情况。
  • idnexWriter和indexReader都是线程安全且是线程友好的( 标记为synchronized的代码并不多,仅为最小值)
  • lucene采用的文件锁:如果锁文件(默认是write.lock)存在你的索引目录内,说明此时有一个writer打开了索引,如果针对同一索引创建一个新的writer的话,将产生一个lockObtainFailedException异常。这是一个重要保护机制,因为针对同一索引打开两个writer,会导致索引锁坏。
  • 参看有关刷新和段合并的有关信息:IndexWriterConfig conf = new IndexWriterConfig(analyzer);
    conf.setInfoStream(System.out);
lucene4.5源码分析系列:lucene概述 lucene索引格式:http://www.cnblogs.com/forfuture1978/archive/2009/12/14/1623597.html 阅读详情

相关推荐

从抽象到实现:Elasticsearch数据类型及其底层Lucene数据结构的深度解析

Elasticsearch的强大功能根植于其核心——Apache Lucene,一个高性能、功能完备的搜索引擎库 1。要深入理解Elasticsearch如何处理各种数据类型,首先必须剖析构成Lucene索引的三个基本数据结构:倒排索引(Inverted Index)、列式存储(Doc Values)和BKD树(BKD Tree)。这三大支柱各自针对不同的访问模式进行了极致优化,它们的协同工作构成了现代搜索引擎的基石。倒排索引是Lucene乃至所有现代搜索引擎实现快速全文检索的核心数据结构 2。其基本思想与

qq_29328443的博客 1217

Lucene/Solr Optimize相关总结

Optimize就是优化的意思。说到Optimize,其实问题回归到两个本质问题:updata-in-place/update-out-of-place、restart。1WhenOptimize索引update、deleted、add、update、deleted、add反反复复,导致索引“千仓百孔”、“指针琳琳散散”、“无用数据或者辅助数据增多”,最后影响相同的查询逻辑,...

weixin_34409703的博客 345

ElasticSearch索引更新背后的秘密:为什么删除文档后磁盘空间没有立即释放?

本文深入解析了ElasticSearch索引更新机制中删除文档后磁盘空间未立即释放的原因,揭示了其基于段(Segment)的不可变数据结构和动态更新索引原理。通过分析段合并触发机制和实际空间回收过程,提供了优化磁盘使用的配置策略和手动回收技巧,帮助开发者更好地管理ElasticSearch存储资源。

weixin_28312391的博客 97

Lucene学习总结之Lucene的索引文件格式

/commit生成segment "_1",由于上次flushDocStores设为false,于是段"_1"的域以及词向量信息是保存在"_0"中的,在这个时刻,段"_1"并不生成自己的"_1.fdx"和"_1.fdt"。然而这时,DocumentsWriter中的docStoreSegment= "_1",也即当段"_2"存储其域和词向量信息的时候,是存在"_1.fdx"和"_1.fdt"中的,而段"_1"的域和词向量信息却是存在"_0.fdt"和"_0.fdx"中的,这一点非常令人困惑。

时光の尘的博客 1245

Lucene(5):索引维护

管理人员通过电商系统更改图书信息,这时更新的是关系数据库,如果使用lucene搜索图书信息,需要在数据库表book信息变化时及时更新lucene索引库。更新索引是先删除再添加,建议对更新需求采用此方法并且要保证对已存在的索引执行更新,可以先查询出来,确定更新记录存在执行更新操作。索引删除后将放在Lucene的回收站中,Lucene3.X版本可以恢复删除的文档,3.X之后无法恢复。将索引目录的索引信息全部删除,直接彻底删除,无法恢复。根据Term项删除索引,满足条件的将全部删除。参考入门程序的创建索引。

u013938578的博客 868

Lucene增量索引的奥秘

随着实时搜索、实时分析等需求的增长,对索引更新的实时性要求也越来越高。如何进一步缩短新文档可被检索的延迟,同时保证系统的稳定性和查询性能,是增量索引技术未来的一大挑战。在Lucene中实现自定义分词器需要继承Tokenizer类,并实现其方法。继承Tokenizer类:创建一个新的类继承Tokenizer。实现incrementToken方法:在该方法中实现自定义的分词逻辑。注册分词器:将自定义分词器注册到Lucene的分析器中。

AI天才研究院 1073

lucene实时 增量索引_什么是Lucene

Lucene最受欢迎的java开源全文搜索引擎开发工具包。提供了完整的查询引擎和索引引擎,部分文本分词引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便在目标系统中实现全文检索功能,或者是以此为基础建立起完整的全文检索引擎。是Apache的子项目,网址:http://lucene.apache.org/用途为软件开发人员提供一个简单易用的工具包,以方...

weixin_39767322的博客 318

Lucene索引操作实战Demo(创建、增删改查完整流程)

Lucene并非开箱即用的搜索引擎,而是一个高可定制化的全文检索库,其设计核心在于“倒排索引”机制。通过将文档内容拆解为词项(Term),建立“词 → 文档”的映射关系,实现高效的关键字匹配。整个系统围绕写入索引、读取索引、Directory管理存储路径、Analyzer处理文本四大支柱构建。// 示例:基本组件协作示意该代码片段展示了Lucene组件间的依赖关系:Directory负责物理存储,Analyzer定义分词逻辑,封装配置策略,最终由。

weixin_42361478的博客 1006

Lucene可以同时删除和更新!

很久以前,Lucene只能使用单个线程将新段写入磁盘。 文档的实际索引是将传入文档转换为内存中段数据结构的昂贵过程,可以使用多个线程运行,但那时,将这些内存中索引写入Lucene段的过程是单线程的。 我们修复了这一问题, 现在已经有6年多了 , 在并发硬件上可以产生很大的索引吞吐量 。 如今,硬件变得更加并发了,我们终于在处理已删除的文档和更新doc值方面做了同样的事情! 在Lu...

danpu0978的博客 179

告别C盘爆红!手把手教你将WSL2下的Ubuntu 22.04完整迁移到D盘(附清理指南)

本文详细指导如何将WSL2下的Ubuntu 22.04从C盘无损迁移到D盘,包括导出备份、注销原系统、导入新位置等关键步骤,并提供迁移后的优化配置、开发环境衔接及长期维护技巧,帮助用户彻底解决C盘空间不足问题。

weixin_28698059的博客 472

LVDS系列23:Xilinx Ultrascale系ISERDESE3原语(一)

当FIFO_RD_CLK与CLKDIV对齐时,也就是Latency With Late FIFO Empty情况时,延迟比前一种情况长一个FIFO_RD_CLK时钟周期,也就是在FIFO_RD_CLK上升沿后一点,CLKDIV才成功驱动完FIFO_EMPTY的变化,于是读侧要得到FIFO_EMPTY为0的情况则要等到下一个FIFO_RD_CLK的上升沿采集时;IS_CLK_INVERTED、IS_CLK_B_INVERTED设置CLK和CLK_B是否反转,一般情况下设置0;

weixin_38828382的博客 900

Elasticsearch 更新与删除机制深度解析:不可变文档下的高效设计

的机制,在保持文档不可变性的同时,实现了高效的更新与删除功能。理解这一设计,有助于优化索引性能并规避潜在问题。Elasticsearch(ES)作为一款高性能的分布式搜索引擎,其底层存储引擎基于。本文将深入剖析 ES 的更新与删除流程,揭示其背后的高效设计。:删除操作的性能瓶颈在于段合并频率,高频删除场景需优化。逻辑删除的文档会一直占用磁盘空间,直到触发。在 ES 7.0+ 中,删除标记机制优化为。由于文档不可变,ES 的更新操作实际上是。,而 Lucene 的核心设计之一就是。当执行删除操作时,ES。

用文字记录技术,用分享回馈社区,用坚持见证成长 1151

gephi生成网络关系图_路网拓扑重建专题 (3) 网络图生成

城市道路网建模在获得基础路网之后,需要考虑道路交通网络的描述与表达问题。网络是将现实世界中的事物及其关系进行适当的抽象,构造成由节点和边按照一定规则组成的形式。一个实体网络可以由有限个“节点”集合与“边”集合构成的图表示,即网络表示为。对于一个由个节点组成的无权复杂网络,该图有邻接矩阵,这里。根据研究对象不同,建模方法主要包括原始法[1]和对偶法[2]两种,见图1,字母a-j为交叉口编号...

weixin_39761195的博客 3502

关于Lucene的学习

关于ES的学习Elasticsearch简介新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 Elasticsearch简介 ES的核心基于Lucene进行封装,提供较简单易用的restful API接口以及java API

Swaggg_的博客 324

RBF(径向基神经网络)基础解析与代码实例:拟合任意函数

目前RBF这一强大工具已经被基本证实可以拟合任意函数! 在机器学习领域,神经网络是一种强大的工具,用于解决各种复杂问题。其中,径向基函数(RBF,Radial Basis Function)神经网络以其独特的结构和优异的性能,在非线性函数逼近、模式识别等领域表现尤为突出。RBF神经网络是一种前馈神经网络,其隐含层节点的激活函数采用径向基函数,具有更强的局部逼近能力和更快的收敛速度。

橙色小博的博客,励志在人工智能领域发光发热! 1603

MindIE与vLLM-Ascend性能对决:Qwen3在昇腾910B上的推理效率实测

本文深度对比了昇腾910B平台上两大推理框架MindIE与vLLM-Ascend的性能表现。通过实测Qwen3系列模型,详细分析了二者在单卡、多卡场景下的推理效率、扩展性及生产环境适用性,为AI算力基础设施选型提供关键参考。

weixin_29214335的博客 1181

Lucene 内部结构解析: Elasticsearch 核心的秘密

Lucene的核心内部结构主要由倒排索引、分词器、评分算法(如BM25)、段(Segment)管理机制组成。倒排索引将单词映射到文档,实现高效检索;分词器处理文本分割;评分机制排序结果;段优化存储与查询性能。这些组件协同工作,确保快速准确的搜索功能。

蓝鲸鱼计算机软件开发工作室 915

AP发票批量付款程序(WEB ADI)

CREATE OR REPLACE PACKAGE MEW_AP_BATCH_PAYMENTS_PKG IS   PROCEDURE MAIN(P_BATCH_ID          NUMBER                 ,P_ORG_ID            NUMBER                 ,P_BANK_ACCOUNT_NAME VARCHAR2

储藏室 5050

Lucene系列六:索引过程和IndexWriter

索引过程是由Lucene所提供的核心功能之一,而IndexWriter 是索引过程中最重要的和核心组件。 目录 1. 索引基本流程 2. IndexWriter 2.1. 关于线程安全 2.2. IndexWriterConfig 2.3 核心API 2.4 演示实例 3. 数据存储格式 4. 总结 1. 索引基本流程 索引文件的写入顺序: fdt--->fdx -...

布道 6826

【QGIS入门实战精品教程】1.2:QGIS与ArcGIS的区别和联系

以下是GISGeography官方给出的两者之间的27点比较(译): 官方网址:https://gisgeography.com/qgis-arcgis-differences/ 1.QGIS容纳更多的数据格式 ArcGIS没有支持所有的数据格式,毫无疑问,QGIS在处理各种类型的数据时非常顺手,QGIS在数据格式方面是个多面手,在使用数据方面是它的长处。 QGIS使用GDAL/OGR库来读取和写入地理信息数据格式,支持超过70种矢量格式。QGIS一开始就是为了与PostGIS协作而诞生的,而支持的名单.

智慧空间实验室 2040

想重装OpenClaw?先执行这4步彻底卸载,避免配置冲突

在重装OpenClaw之前,彻底卸载是非常重要的一步。如果不彻底卸载,可能会导致: - 残留的配置文件与新安装的版本冲突 - 旧的依赖包干扰新的安装过程 - 服务冲突导致启动失败 - 数据混乱影响系统稳定性

一键难忘的博客 1043

Lucene.NET 若干知识点&&疑难杂症以及解决

1.new Field("id", package.Id.ToString(), Field.Store.YES, Field.Index.TOKENIZED)   几个字段解析,“id”:索引字段的KEY,package.Id.ToString(),索引的值,Field.Store.YES,是否将值存入,如果是NO,该字段值无法提取出,Field.Index.TOKENIZED这个...

148

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Elasticsearch字段删除的底层机制:从标记删除到段合并的完整生命周期

本文深入解析Elasticsearch字段删除的底层机制,从标记删除到段合并的完整生命周期。详细介绍了Update API的标记删除、Reindex API的文档重建以及映射更新+Reindex的彻底清除三种实现方式,并探讨了Lucene段文件与删除标记的物理存储原理。同时提供了性能优化建议和疑难问题排查方案,帮助开发者高效管理Elasticsearch索引。

garlic的博客 763

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

【Lucene】Lucene的索引文件格式:深入理解Lucene使用的索引文件格式

Lucene的索引文件格式设计精妙,利用模块化和压缩技术实现了存储空间与查询效率的平衡。segments_N是索引的全局入口,.tis和.tii负责词典管理,.frq和.prx记录倒排索引的数据,.fdt和.fdx提供字段存储支持。通过这些文件的协作,Lucene能够在大规模数据中实现高效的全文检索。

weiliang_Handan的博客 1302

lucene的增删改查

1、建立一个Article简单java类public class Article { public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return titl

种花家的博客 636
上一篇: es-怎么将嵌套对象打平
下一篇: lucene原理篇
带着托托写代码
博客等级 码龄10年 113粉丝 90原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值