搜索引擎索引之如何更新索引

article/2025/10/9 16:30:17

                                         本文节选自《这就是搜索引擎:核心技术详解》第三章

     动态索引通过在内存中维护临时索引,可以实现对动态文档和实时搜索的支持。但是服务器内存总是有限的,随着新加入系统的文档越来越多,临时索引消耗的内存也会随之增加。当最初分配的内存将被使用完时,要考虑将临时索引的内容更新到磁盘索引中,以释放内存空间来容纳后续的新进文档,此时要考虑合理有效的索引更新策略。

常用的索引更新策略有四种:完全重建策略,再合并策略,就地更新策略以及混合策略。

3.6.1完全重建策略(CompleteRe-Build)

    完全重建策略是一个相当直观的方法,当新增文档达到一定数量,将新增文档和原先的老文档进行合并,然后利用前述章节提到的建立索引的方式,对所有文档重新建立索引。新索引建立完成后,老的索引被遗弃释放,之后对用户查询的响应完全由新的索引负责。图3-16是这种策略的说明示意图。

                    


                            图3-16完全重建策略

      因为重建索引需要较长时间,在进行索引重建的过程中,内存中仍然需要维护老的索引,来对用户的查询做出响应,只有当新索引完全建立完成后,才能释放旧的索引,将用户查询响应切换到新索引上。

这种重建策略比较适合小文档集合,因为完全重建索引的代价较高,但是目前主流商业搜索引擎一般是采用此种方式来维护索引的更新,这与互联网本身的特性有关。


3.6.2再合并策略(Re-Merge)

  

    有新增文档进入搜索系统时,搜索系统在内存维护临时倒排索引来记录其信息,当新增文档达到一定数量,或者指定大小的内存被消耗完,则把临时索引和老文档的倒排索引进行合并,以生成新的索引。图3-17是这种策略的一种图示。

                      

  

                              图3-17 再合并策略

     在实际的搜索系统中,“再合并策略”按照以下步骤进行索引内容的更新:

    当新文档进入系统,解析文档,之后更新内存中维护的临时索引,文档中出现的每个单词,在其倒排列表末尾追加倒排列表项,这个临时索引可称之为“增量索引”;

    一旦“增量索引”将指定的内存消耗光,此时需要进行一次索引合并,即将“增量索引”和老的倒排索引内容进行合并。图3-18是合并过程示意图,这里需要注意的是:倒排文件里的倒排列表存放顺序,已经按照索引单词字典顺序由低到高进行了排序,增量索引在遍历词典的时候也按照字典序由低到高排列,这样对老的倒排文件只需进行一遍扫描,并可顺序读取,减少了文件操作中比较耗时的磁盘寻道时间,可以有效地增加合并效率。

 

 

 

                         图3-18 合并增量索引与倒排索引

 

      在合并过程中,需要依次遍历“增量索引”和老索引单词词典中包含的单词及其对应的倒排列表,可以用两个指针分别指向两套索引中目前需要合并的单词(参考图3-18中箭头所指),按照如下方式进行倒排列表的合并:

      考虑“增量索引”的单词指针指向的单词,如果这个单词在词典序中小于老索引的单词指针指向的单词,说明这个单词在老索引中没有出现过,则直接将这个单词对应的倒排列表写入新索引的倒排文件中,同时“增量索引”单词指针后移指向下一个单词。

     如果两个“单词指针”指向的单词相同,说明这个单词在“增量索引”和老索引中同时出现,则将老索引中这个单词对应的倒排列表写入新索引的倒排列表,然后把“增量索引”中这个单词对应的倒排列表追加到其后,这样就完成了这个单词所有倒排列表的合并。图3-18中箭头所指单词是“搜索”,说明此时合并到了该单词,因为在老的索引系统和增量索引中都包含这个单词,所以首先将老索引对应的倒排列表追加到新索引倒排文件末尾,之后将增量索引中“搜索”这个单词对应的倒排列表追加在其后,这样就完成了这个单词索引项的合并。两个索引的单词指针都移动到下一个单词继续进行合并。

     如果某个单词只在老索引中出现过,即发现老索引的“单词指针”指向的单词,其词典序小于“增量索引”单词指针指向的单词,则直接将老索引中对应的倒排列表写入新索引倒排文件中。老索引的单词指针后移指向下一个单词,继续进行合并。

      当两个索引的所有单词都遍历完成后,新索引建成,此时可以遗弃释放老索引,使用新索引来响应用户查询请求。

      同样的,在按照这个策略进行索引合并的过程中,为了能够响应用户查询,在合并索引期间,需要使用老索引响应用户查询请求。

       “再合并策略”是效率非常高的一种索引更新策略,主要原因在于:在对老的倒排索引进行遍历时,因为已经按照索引单词的词典序由低到高排好顺序,所以可以顺序读取文件内容,减少了磁盘寻道时间,这是其高效的根本原因。但是这种方法也有其缺点,因为要生成新的倒排索引文件,所以对于老索引中的很多单词来说,尽管其倒排列表并未发生任何变化,但是也需要将其从老索引中读取出来并写入新索引中,这种对磁盘输入输出的消耗是没有太大必要且非常耗时的。


3.6.3原地更新策略(In-Place)

      原地更新策略的基本出发点,可以认为是试图改进“再合并策略”的缺点。就是说,在索引更新过程中,如果老索引的倒排列表没有变化,可以不需要读取这些信息,而只对那些倒排列表变化的单词进行处理。甚至希望能更进一步:即使老索引的倒排列表发生变化,是否可以只在其末尾进行追加操作,而不需要读取原先的倒排列表并重写到磁盘另外一个位置? 如果能够达到这个目标,明显可以大量减少磁盘读写操作,提升系统执行效率。

     为了达到上述目标,原地更新策略在索引合并时,并不生成新的索引文件,而是直接在原先老的索引文件里进行追加操作(参考图3-19),将增量索引里单词的倒排列表项追加到老索引相应位置的末尾,这样就可达到上述目标,即只更新增量索引里出现的单词相关信息,其它单词相关信息不做变动。


                            图3-19 原地更新策略

 

     但是这里存在一个问题:对于倒排文件中的两个相邻单词,为了在查询时加快读取速度,其倒排列表一般是顺序序列存储的,这导致没有空余位置用来追加新信息。为了能够支持追加操作,“原地更新策略”在初始建立的索引中,会在每个单词的倒排列表末尾预留出一定的磁盘空间,这样,在进行索引合并时,可以将增量索引追加到预留空间中。

    图3-20是这种合并策略的一个说明。在图中,老索引中每个单词的倒排列表末尾都预留出空余磁盘空间,以作为信息追加时的存储区域。在对“新增索引”进行合并时,按照词典序,依次遍历“新增索引”中包含的单词,并对新增倒排列表的大小和老索引中相应预留空间大小进行比较,如果预留空间足够大,则将新增列表追加到老索引即可,如果预留空间不足以容纳新增倒排列表,那么此时需要在磁盘中找到一块完整的连续存储区,这个存储区足以容纳这个单词的倒排列表,之后将老索引中的倒排列表读出并写入新的磁盘位置,并将“增量索引”对应的倒排列表追加到其之后,这样就完成了一次倒排列表的“迁移”工作。

      

      

                            图3-20原地更新策略索引合并

     在图3-20所示的例子中,可以看出,单词“技术”和“引擎”在老索引中的预留空间足够大,所以对“增量索引”只需做追加写入即可,但是对于单词“搜索”来说,其预留空间不足以容纳新增倒排列表,所以这个单词的倒排列表需要迁移到磁盘另外一个连续存储区中。

“原地更新策略”的出发点很好,但是实验数据证明其索引更新效率比“再合并策略”要低,主要是出于以下两个原因:

       在这种方法中,对倒排列表进行“迁移”是比较常见的操作,为了能够进行快速迁移,需要找到足够大的磁盘连续存储区,所以这个策略需要对磁盘可用空间进行维护和管理,而这种维护和查找成本非常高,这成为该方法效率的一个瓶颈。

     对于倒排文件中的相邻索引单词,其倒排列表顺序一般是按照相邻单词的词典序存储的,但是由于“原地更新策略”对单词的倒排列表做数据迁移,某些单词及其对应倒排列表会从老索引中移出,这样就破坏了这种单词连续性,导致在进行索引合并时不能顺序进行读取,必须维护一个单词到其倒排文件相应位置的映射表,而这样做,一方面降低了磁盘读取速度,另外一方面需要大量的内存来存储这种映射信息。

 

3.6.4混合策略(Hybrid)

     混合策略的出发点是能够结合不同索引更新策略的长处,将不同的索引更新策略混合,以形成更高效的方法。

混合策略一般会将单词根据其不同性质进行分类,不同类别的单词,对其索引采取不同的索引更新策略。常见的做法是根据单词的倒排列表长度进行区分,因为有些单词经常在不同文档中出现,所以其对应的倒排列表较长,而有些单词很少见,则其倒排列表就较短。根据这一性质将单词划分为“长倒排列表单词”和“短倒排列表单词”。“长倒排列表单词”采取“原地更新策略”,而“短倒排列表单词”则采取“再合并策略”。

之所以这样做,是由于“原地更新策略”更适合“长倒排列表单词”,因为这种策略能够节省磁盘读写次数,而“长倒排列表单词”的读写开销明显要比“短倒排列表单词”大很多,所以如果采用“原地更新策略”,效果体现得比较显著。而大量“短倒排列表单词”读写开销相对而言不算太大,所以利用“再合并策略”来处理,则其顺序读写优势也能被充分利用。



http://chatgpt.dhexx.cn/article/E0hyfdAJ.shtml

相关文章

IDEA总是自动更新索引怎么解决

从File进入settings 搜索index_>修改右边的两个即可,点击OK保存即可

项目中如何使用ElasticSearch?变更数据时难道既更新数据库也要更新索引?这篇文章也许对你有点帮助(持续更新)

目录 1. 概述2.ElasticSearch的调试2.1 启动ES2.2 创建搜索的微服务2.3 使用logstash同步数据库数据到es的索引中 3.Linux系统下部署3.1 拉取es容器3.2 让9300端口可用3.3 安装ik分词器3.4 安装head-master3.5 配置logstash(耗时最久) 四. 出现的bug4.1 …

【Mysql】 sql语句实现update_or_create(唯一索引 ON DUPLICATE KEY UPDATE)

【Mysql】 on duplicate key update用法、优缺点以及使用案例 1. 应用场景: 导入数据功能,需要实现数据不存在时进行新建,有数据修改时则进行更新。在实现时,思路通常为先判断数据是新增还是更新,除了我们在代码层面实…

mysql-索引

1.索引的定义: 索引是帮助MySql高效获取数据的数据结构。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索…

mysql中的各种索引大总结

文章目录 为啥不用二叉搜索树?为啥不用平衡二叉(avl)树?为啥不用b-树?为啥用b树?(重点)索引聚簇索引聚簇索引的局限聚集的数据的优点非聚簇索引介绍组合索引覆盖索引前缀索引前缀索引…

MySQL索引的更新策略

对于数据的每一次更新,MySQL并不会每次都会更新索引(针对非唯一性索引而言),索引的更新策略是这样的: 在InnoDB中,增删改都会立刻修改主键or唯一索引,但是不会rebuild全局索引,而是对这些索引增加值(或移除…

苹果各机型尺寸大小

//6.5英寸 #define iPhoneXSMax ([UIScreen instancesRespondToSelector:selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1242, 2688), [[UIScreen mainScreen] currentMode].size) : NO) //6.1英寸 #define iPhoneXR ([UIScreen instancesRespondToSelector:selec…

iOS 手机尺寸

iPhone设备 物理分辨率是硬件所支持的,逻辑分辨率是软件可以达到的。 代数设备操作系统逻辑分辨率(point)物理分辨率(pixel)屏幕尺寸(对角线长度)缩放因子 iPhone 第一代iPhone 2GiOS 1320 x 480480 x 3203.5寸1x第二代iPhone 3iOS 2320 x 480480 x 3203.5寸1…

jQuery weui 时间选择器datetimepicker年月日最简单解决方案

使用jqweui的时候发现,datetimePicker(时间日期选择器)竟然不提供只有年月日这种模式,真是牛逼(垃圾),跟着我,只需要很简单的修改就好了,上图 下面是js $("#datati…

jquery weui 显示loading

jQuery weui 显示loading按钮官方文档并没有给出demo&#xff0c;经过调试&#xff0c;把代码给拷贝了出来。 实现显示loading的代码如下&#xff1a; <div id"loadDiv" style"display: none;" class"weui-toast weui_loading_toast weui-toast--…

$ppclass php,jquery weui

"weui-tab"!----"weui-"!--二级页积分详情--"""weui--itemweui-tab__bd-item--active"divclass"details"divclass"page-header"?Html::img($this-theme-getAssetUrl(images/logo.png),[classlogo])?/divahref&q…

移动端框架之JQuery WeUI

和JQuery WeUI 配合使用的WeUI&#xff0c;是移动端快速开发的利器。 在初步使用的过程中&#xff0c;发现JQuery WeUI扩展的几个功能特别实用&#xff1a; 1.通知&#xff1a;模仿iOS风格的通知。你可以自定义标题&#xff0c;文案和图标。通过滑动手势可以关闭。 这种通知形…

基于Jquery WeUI的微信开发H5页面控件的经验总结(2)

在微信开发H5页面的时候&#xff0c;往往借助于WeUI或者Jquery WeUI等基础上进行界面效果的开发&#xff0c;由于本人喜欢在Asp.net的Web界面上使用JQuery&#xff0c;因此比较倾向于使用 jQuery WeUI&#xff0c;本篇随笔结合官方案例和自己的项目实际开发过程的经验总结&…

jquery weui 图片浏览器Photo Browser 如何使用?

对应组件地址&#xff1a;http://jqweui.com/extends#swiper 先说说业务场景&#xff1a;类似朋友圈这样的布局效果&#xff0c;点击小图可以浏览大图&#xff0c;并支持大图左右切换&#xff0c;效果图如下&#xff08;加了滚动加载更多的操作在里面&#xff09;&#xff1a;…

jQuery WeUI日历calendar时间段(开始日期默认选中日期是今天,结束日期设置最小日期),显示日期格式是yyyy年mm月dd日

jQuery WeUI官网&#xff1a; https://jqweui.cn(国内) 说明 日历calendar时间段为两段&#xff0c;开始日期和结束日期。 开始日期&#xff1a;打开后&#xff0c;默认选中日期是今天。 结束日期&#xff1a;打开后&#xff0c;默认选中和最小日期是开始日期。 html <d…

【WeUI】关于jQuery WeUI和WeUI版本兼容的问题

最近做的一个小demo&#xff0c;在添加Dialog的时候出现了对话框显示的问题&#xff0c;如下左图所示。 一开始以为自己的写的CSS文件影响了&#xff0c;注释掉还是这个问题&#xff0c;所以问题指向很明确了&#xff0c;是官方weui.css的问题。但是官方demo里的运行是正常显示…

jQueryWEUI自定义对话框-带有textarea

jQueryWEUI 示例下载 在jQueryWEUI中提供了很多类型的对话框&#xff0c; 可以去访问看一下。 今天记录的则是&#xff0c;自己定义的一个带有文本域的对话框&#xff0c;这样&#xff0c;可以不通过调转页面&#xff0c;实现一些信息的提交。比如&#xff0c;发送留言&#x…

jQuery weui 时间选择器datetimepicker只用年月日

<input placeholder"请选择出生日期" name"birth_time" type"text" iddatetime-picker />let allTime ;var myDate new Date();//let CreateDateLessD myDate.getFullYear() "-" (myDate.getMonth() 1) "-" …

关于Jqueryweui 的select联动用法

在使用Jquery weui 框架时&#xff0c;我想实现根据收货地址获得该条收货地址的绑定的联系人和电话。 但是又懒得根据收货地址查询联系人和联系电话。&#xff08;因为收货地址都是从数据库获取的&#xff0c;此时不仅拿到了收货地址&#xff0c;还拿到了联系人和联系电话&…

jQuery WeUI 上传

jQuery WeUI 是专为微信公众账号开发而设计的一个框架&#xff0c;jQuery WeUI的官网&#xff1a;http://jqweui.com/ 需求&#xff1a;需要在微信公众号网页添加上传图片功能 技术选型&#xff1a;实现上传图片功能可选百度的WebUploader、饿了么的Element和微信的jQuery We…