Lucene随笔-聊聊IndexWriter

2024-06-19 20:08

本文主要是介绍Lucene随笔-聊聊IndexWriter,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Lucene版本:6.5.1
Package: org.apache.lucene.index;

IndexWriter示例

这里以"hello world"的索引过程为例,探究以下IndexWriter的原理:

  • doc1:索引文件。
  • path: 索引相关的文件所存放的文件夹位置。

IndexWriter的大致过程如下:

  1. 首先创建IndexWriter。
  2. 创建需要索引的文档。
  3. 通过IndexWriter将文档写入。
  4. 提交以及关闭IndexWriter。
		String doc1 = "hello world";String path = "pathFile";// 创建IndexWriterDirectory d = FSDirectory.open(Paths.get(PATH));IndexWriterConfig conf = new IndexWriterConfig(new SimpleAnalyzer());IndexWriter indexWriter = new IndexWriter(d, conf);// 把要创建的索引的文本数据放入Document中Document ducument1 = new Document();ducument1.add(new TextField("id", "1", Field.Store.YES));// 通过IndexWriter把Document写入indexWriter.addDocument(ducument1);// 调用commit函数将数据组合成segment,这个时候数据才能被检索indexWriter.commit();indexWriter.close();

整个查询流程总结如下:

  • 初始化:初始化IndexWriter必要的两个元素是Directory和IndexWriterConfig,Directory是Lucene中数据持久层的抽象接口,通过这层接口可以实现很多不同类型的数据持久层,例如本地文件系统、网络文件系统、数据库或者是分布式文件系统。这里lucene里面说明了采用NFS的模式相对于本地文件系统会导致性能下降。
  • 构造文档:Lucene中文档由Document表示,Document由Field构成。
  • 写入文档:通过IndexWriter的addDocument函数写入文档,写入时同时根据FieldType创建不同的索引。
  • 提交刷新文档:当数据写入后并不是立即搜索的,需要调用commit函数,这时候会手动出发一次flush才能将数据组织成segment实现可检索。

IndexWriter创建

Class IndexWriterConfig

IndexWriterConfig里面包含了IndexWriter的配置情况,包括索引以何种形式写入、分析器的类型等等。
注意:用这个配置对象创建好IndexWriter对象后,再修改这个配置对象的配置信息不会对IndexWriter对象起作用。如要在indexWriter使用过程中修改它的配置信息,通过 indexWriter的getConfig()方法获得 LiveIndexWriterConfig 对象,在这个对象中可查看该IndexWriter使用的配置信息,可进行少量的配置修改

其中部分的核心参数如下:

  • OpenMode: IndexWriter的打开方式,包含了三种模式(CREATE, APPEND, CREATE, CREATE_OR_APPEND), CREATE表示新建或者重写一个index;APPEND表示打开一个存在的index;CREATE_APPEND表示
  • IndexDeletionPolicy:Lucene开放对commit point的管理,通过对commit point的管理可以实现例如snapshot等功能。Lucene默认配置的DeletionPolicy,只会保留最新的一个commit point。
  • Similarity:搜索的核心是相关性,Similarity是相关性算法的抽象接口,Lucene默认实现了TF-IDF和BM25算法。相关性计算在数据写入和搜索时都会发生,数据写入时的相关性计算称为Index-time boosting,计算Normalizaiton并写入索引,搜索时的相关性计算称为query-time boosting。
  • MergePolicy:Lucene内部数据写入会产生很多Segment,查询时会对多个Segment查询并合并结果。所以Segment的数量一定程度上会影响查询的效率,所以需要对Segment进行合并,合并的过程就称为Merge,而何时触发Merge由MergePolicy决定。
  • MergeScheduler:当MergePolicy触发Merge后,执行Merge会由MergeScheduler来管理。Merge通常是比较耗CPU和IO的过程,MergeScheduler提供了对Merge过程定制管理的能力。
  • Codec:Codec可以说是Lucene中最核心的部分,定义了Lucene内部所有类型索引的Encoder和Decoder。Lucene在Config这一层将Codec配置化,主要目的是提供对不同版本数据的处理能力。对于Lucene用户来说,这一层的定制需求通常较少,能玩Codec的通常都是顶级玩家了。
  • IndexerThreadPool:管理IndexWriter内部索引线程(DocumentsWriterPerThread)池,这也是Lucene内部定制资源管理的一部分。
  • FlushPolicy:FlushPolicy决定了In-memory buffer何时被flush,默认的实现会根据RAM大小(默认16mb)和文档个数来判断Flush的时机,FlushPolicy会在每次文档add/update/delete时调用判定。
  • MaxBufferedDoc:Lucene提供的默认FlushPolicy的实现FlushByRamOrCountsPolicy中允许DocumentsWriterPerThread使用的最大文档数上限,超过则触发Flush。
  • RAMBufferSizeMB:Lucene提供的默认FlushPolicy的实现FlushByRamOrCountsPolicy中允许DocumentsWriterPerThread使用的最大内存上限,超过则触发flush。
  • RAMPerThreadHardLimitMB:除了FlushPolicy能决定Flush外,Lucene还会有一个指标强制限制DocumentsWriterPerThread占用的内存大小,当超过阈值则强制flush, 默认为1945MB。
  • Analyzer:即分词器,这个通常是定制化最多的,特别是针对不同的语言,默认的初始化函数使用的是StandardAnalyzer分析器。

Class IndexWriter

在建立IndexWriter时候,需要设定Directory 与IndexWriterConfig 。其中Directory 为索引保存的文件,而IndexWriterConfig则是indexwriter的配置情况,其中IndexWriter主要提供的核心API如下:

  • addDocument:比较纯粹的一个API,就是向Lucene内新增一个文档。Lucene内部没有主键索引,所有新增文档都会被认为一个新的文档,分配一个独立的docId。
  • updateDocuments:更新文档,但是和数据库的更新不太一样。数据库的更新是查询后更新,Lucene的更新是查询后删除再新增。流程是先delete by term,后add document。但是这个流程又和直接先调用delete后调用add效果不一样,只有update能够保证在Thread内部删除和新增保证原子性,详细流程在下一章节会细说。
  • deleteDocument:删除文档,支持两种类型删除,by term和by query。在IndexWriter内部这两种删除的流程不太一样,在下一章节再细说。
  • flush:触发强制flush,将所有DWPT的In-memory buffer flush成segment文件,这个动作可以清理内存,强制对数据做持久化。
  • prepareCommit/commit/rollback:commit后数据才可被搜索,commit是一个二阶段操作,prepareCommit是二阶段操作的第一个阶段,也可以通过调用commit一步完成,rollback提供了回滚到last commit的操作。
    maybeMerge/forceMerge:maybeMerge触发一次MergePolicy的判定,而forceMerge则触发一次强制merge。

Document创建

要索引的数据记录、文档在lucene中的表示,是索引、搜索的基本单元。一个Document由多个字段Field构成。IndexWriter按加入的顺序为Document指定一个递增的id(从0开始),称为文档id。反向索引中存储的是这个id,文档存储中正向索引也是这个id。 业务数据的主键id只是文档的一个字段。

Document主要由一组IndexableFields构成,除了提供添加和删除的接口外,在Doc内部提供了各种API用于获取Doc内部的Fields。

Class IndexableField

其为一个接口,包含了字段名,字段值,字段类型。

public interface IndexableField {// field名字String name();// 字段类型IndexableFieldType fieldType();// 下面的API都是获取各种字段值的接口。TokenStream tokenStream(Analyzer var1, TokenStream var2);/** @deprecated */@Deprecatedfloat boost();BytesRef binaryValue();String stringValue();Reader readerValue();Number numericValue();
}

其中字段类型主要有以下几个内容:

  • stored:是否存储
  • tokenized:是否分词。
  • omitNorms:是否忽略标准化。
  • indexOptions:如何索引。
  • storeTermVectors:是否存储词项向量。
  • storeTermVectorOffset: 词项向量中是否存储偏移量。
  • storeTermVectorPositions: 词项向量中是否存储偏位置。
  • storeTermVectorPaykoads: 词项向量中是否存储偏附加信息。

Lucene预定义的字段字类

  • TextField:会自动被索引和分词的字段。一般被用在文章的正文部分。
  • StringField:会被索引,但是不会被分词,即会被当作一个完整的token处理,一般用在“国家”或者“ID”。
  • IntPoint/LongPoint/FloatPoint/DoublePoint:indexed for exact/range queries.
  • SortedDocValuesField
  • SortedSetDocValuesField
  • NumericDocValuesField
  • SortedNumericDocValuesField
  • SortedField: 一个默认会被存储的Field。

这篇关于Lucene随笔-聊聊IndexWriter的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1076017

相关文章

聊聊说话的习惯

1 在日常生活中,每个人都有固定的说话习惯。心理学研究表明,通过一个人的说话习惯,也可以分析出他的性格特点。对于每一个人来讲,说话习惯已经融为他们生活中的一部分。在社交活动中,一些不良的说话习惯很可能会给他们带来麻烦。因此,了解说话习惯对心理活动的影响是十分有必要的。 2 具有顺畅的说话习惯的人,大多思路清晰、语速适中、用词准确并且声声人耳,是典型的顺畅型说话方式这种类型的人要么不说话,要么

聊聊分布式,再讨论分布式解决方案

前言 最近很久没有写博客了,一方面是因为公司事情最近比较忙,另外一方面是因为在进行 CAP 的下一阶段的开发工作,不过目前已经告一段落了。 接下来还是开始我们今天的话题,说说分布式事务,或者说是我眼中的分布式事务,因为每个人可能对其的理解都不一样。 分布式事务是企业集成中的一个技术难点,也是每一个分布式系统架构中都会涉及到的一个东西,特别是在微服务架构中,几乎可以说是无法避免,本文就分布式事

聊聊资源调度

资源调度 般分为两个阶段: 是实现物理资源的虚拟化(即资源的抽象)于当前机器的性能越来越好,硬件配置越来越高,直接用物理机跑业务比较浪费,所以将物理机分割成更小单位的虚拟机,这样可以显著提升机器的利用效率,在公司内部一般采用容器技术来隔离资源 是将资源虚拟化后进 步在时间和空间上实现更细粒度的编排 ,优化资源的使用。 1 .一些数据 如果公司的几万台机器都是物理机,那么资源的使用率稍低: CP

MySQL和Lucene(Elasticsearch)索引对比分析

点击上方蓝色字体,选择“设为星标” 回复”资源“获取更多资源 大数据技术与架构 点击右侧关注,大数据开发领域最强公众号! 大数据真好玩 点击右侧关注,大数据真好玩! 本文是来自略速互联网笔记的分享。 你可以在这里查看原文:http://www.lvesu.com/?uri=/blog/main/cms-611.html 前言 相比于大多数人熟悉的 MySQL 数据库的索引,Elasti

聊聊Spark中的宽依赖和窄依赖

开门见山,本文就针对一个点,谈谈Spark中的宽依赖和窄依赖,这是Spark计算引擎划分Stage的根源所在,遇到宽依赖,则划分为多个stage,针对每个Stage,提交一个TaskSet: 上图:一张网上的图: 基于此图,分析下这里为什么前面的流程都是窄依赖,而后面的却是宽依赖: 我们仔细看看,map和filter算子中,对于父RDD来说,一个分区内的数据,有且仅有一个子RDD的分区来

【 Android 应用开发随笔】-- PackageInstaller.SessionCallback

PackageInstaller.SessionCallback 是 Android 开发中的一个接口,用于在应用程序安装过程中接收安装状态的回调。这个接口属于 android.content.pm.PackageInstaller 类,主要用于处理通过 PackageInstaller 类进行的包安装。 主要功能 ◾ 安装进度通知: PackageInstaller.SessionCal

聊聊灰度发布

有没有在北京面试java的小伙伴,每家公司面试问的问题都不一样,昨天面试官问到了灰度发布,一脸懵,好像在哪儿听说过,毕竟我都没发布过,之前都是项目组长在干这些事儿,所以聊聊,了解一下 什么是灰度发布 全量发布:把旧服务kill掉,把新服务启动,这个过程就可以理解为全量发布 回滚周期长 如果我们更新完应用之后,我们做线上回归测试的时候发现有BUG,这个时候就要做回滚,过程就是把新服

聊聊随机测试和猴子测试

目录 随机测试的特点 1.不可预测性 2.缺乏针对性 3.自动化 4.资源密集型 猴子测试 随机测试 (Random Testing) 猴子测试 (Monkey Testing) 特点: 区别 1.控制程度 2.目标差异 3.实现方式 在我们测试的过程中,通常会使用到随机测试和猴子测试,其中随机测试侧重于人工测试,猴子测试侧重于借助工具执行命令进行测试。 随机测试

【聊聊经济社会】论阶级跨越

为什么要在市场中寻求自由,在市场中寻求洒脱,原因不胜其数,其中便有一条,现实生活中多是xx,可能社会属性本身就具备党同伐异,像是一股意志,平庸一切不平庸,中和一切特立独行,最终以达到一种变态的稳定. 消其意志,断其未来,耗其钱财 ,而我称之为阶级壁垒 阶级之所以难以跨越,主要也在于这三点 一:没有这样的志向,像那种羡慕有钱,或者羡慕有权,权当做梦。这样的志向,正常人只停留于羡慕的层次,而一旦受到丁

聊聊PC端页面适配

聊聊PC端页面适配  目也pc端有适配的需求:目前我们pc项目的设计稿尺寸是宽度1920,高度最小是1080。 适配目标: 1.在不同分辨率的电脑上,网页可以正常显示 2.放大或者缩小屏幕,网页可以正常显示 对于宽度的适配   对于宽度适配: 首先设置html,body{width:100%;overflow-x:hidden;} 然后我们可以把页面分解为背景层(