这就是搜索引擎--读书笔记五--索引的建立与更新

索引的建立和更新

索引的建立

前一总结里说到,如果索引结构建立好了,可以提高搜索的速度,那么给定一个文档集合,索引是如何建立起来的呢?建立索引的方式有很多种,在这里我就书中提到的三种方法简单总结一下。

两遍文档遍历法

  • 第一次文档遍历

第一次扫描文档集合时,并没有立即开始建立索引,而是收集一些的统计信息,比如文档集合包含的文档个数N、文档集合内包含的不同单词个数M以及每个单词在哪些文档中出现过的信息DF等等。将所有单词对应的DF值全部相加,就可以知道建立最终的索引需要多少内存了,然后在内存中将连续存储区划分成不同大小的片段,词典内某个单词根据自己对应的DF信息,可以通过指针指向属于自己的内存片段的起始位置和终止位置 , 这样在第二遍扫描中,这个单词对应的倒排列表信息会被填充进这个片段中。

  • 第二次文档遍历

这一次扫描的时候,就开始真正建立每个单词的倒排列表信息了,即对每个单词来说,获得包含这个单词的每个文档的文档ID,以及这个单词在文档中出现的次数,这样就可以不断填充第一次遍历扫描所分配的内存空间。当然,如果要记录单词在文档中出现的位置也是可以的,第一次扫描中分配内存时加上这个位置信息就可以了。

值得注意的是:此方法完全是在内存里完成索引的创建过程的,而后面两种方法则是通过内存和磁盘相互配合来完成索引建立任务的。而正因为创建索引是在内存中完成的,所以就要求内存一定要足够大,否则文档集合太大的话,内存不能够满足需求。而对文档集合进行两遍扫描,所以从速度上相比后面两种方法不占优势。

排序法

排序法在建立索引的过程中,始终在内存中分配固定大小的空间用来存放词典信息和索引的中间结果,当分配的空间被消耗光的时候,把中间结果写入磁盘,清空内存里中间结果所占的空间,以用作下一轮存放索引中间结果的存储区。这种情况下,可以把内存看做驿站,它只是一个中间转折点。这种方法分为两个步骤:中间结果内存排序和合并中间结果。

为什么要进行排序呢主要是为了方便后续的处理。因为在形成中间结果文件前,已经按照单词ID和文档ID进行了排序,所以进入内存缓冲区的数据都是已经排好序的,合并过程中,将不同缓冲区中包含同一个单词ID的信息进行合并,如果某个单词ID的所有信息全部合并完成,那么说明这个单词的倒排列表已经构建完成了,将其写入最终索引中,同时将各个缓冲区中对应这个单词ID信息清空。就这样一直往下进行,直到所有的单词ID对应的倒排列表都已经创建完成。最后的结果,就是最终的索引文件。

归并法

由于排序法有一个不足之处,那就是在将中间结果写入磁盘的时候,词典信息一直在内存中进行维护,这样也会占据一部分的内存。归并法就是对排序法做出了改进,即每次将内存中数据写入磁盘时,包括词典在内的所有中间结果信息都被写入磁盘,这样内存所有内容都可以被清空。

归并法整体流程也是分为两个大的阶段,首先在内存里维护中间结果,当内存占满时,将内存数据写入磁盘临时文件,第二阶段对临时文件进行归并形成最终索引。

归并法和排序法的区别

首先,排序法在内存中存放的是词典信息和三元组数据(单词ID,文档ID,单词频率),在建立索引的过程中,词典和三元组数据并没有直接的联系,词典只是为了将单词映射为单词ID。而归并法则是在内存中建立一个完整的内存索引结构,相当于对目前处理的文档子集建立起了一个倒排索引。

其次,在将中间结果写入磁盘临时文件时,归并法将整个内存的倒排索引写入临时文件,对于某个单词的倒排列表在写入磁盘文件时,将词典项放在列表最前端,之后跟随相应的倒排列表,这样依次将单词和对应的倒排列表写入磁盘文件,随后彻底清空所占内存。而排序法只是将三元组数据排序后写入磁盘文件,词典作为一个映射表一直存储在内存中。

在最后合并为最终索引的过程中,排序法是根据同一单词ID的这样三元组依次进行合并,归并法的临时文件则是每个单词对应的部分倒排列表,所以在合并时针对每个单词的倒排列表进行合并,形成这个单词的最终倒排列表就可以了,与此同时,最后的合并过程中也会形成最终的词典信息。如果大家对算法里的归并排序有所了解的话,就很清楚这种方法了吧。

 

索引更新策略

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

完全重建策略:很直观的方法,当新增文档达到一个数量时,将新增文档和原先的老文档进行合并,然后利用上文提到的建立索引的方式,对所有文档重新建立索引。

再合并策略:有新增文档进入搜索系统时,搜索系统在内存维护临时倒排索引来记录信息,当新增文档达到一定数量的时候,则把临时索引文件和老文档的倒排索引文件进行合并,以生成新的索引。

原地更新策略:在索引合并时,并不生成新的索引文件,而是直接在原先的索引文件里进行追加操作,将增量索引里单词的倒排列表项追加到老索引对应的倒排列表项的末尾,这样的话,就只更新增量索引里出现的单词相关信息,其他单词信息不做变动。

混合策略:结合不同索引更新策略的优势,将不同的索引更新策略混合以形成更高效的方法。

混合策略一般会将单词根据其不同性质进行分类,不同类别的单词,对其索引采取不同的索引更新策略。常见的做法是:根据单词的倒排列表长度进行划分,因为有些单词经常在不同文档中出现,所以其对应的倒排列表就较长,而有些单词很少见,其倒排列表就较短。那么长倒排列表单词采取原地更新策略,因为这种策略能够节省磁盘读写次数;而短倒排列表就采取再和并策略。通过这种根据实际情况来分别采取实际策略的方法,效果体现的比较显著,磁盘的读写操作和各种策略的优势都充分体现出来了。

转载于:https://www.cnblogs.com/BaiYiShaoNian/p/4548817.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/471916.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 1650. 二叉树的最近公共祖先 III(哈希)

文章目录1. 题目2. 解题1. 题目 给定一棵二叉树中的两个节点 p 和 q,返回它们的最近公共祖先节点(LCA)。 每个节点都包含其父节点的引用(指针)。Node 的定义如下: class Node {public int val;public No…

PHP方向+go+rpc+swoole,瞅瞅 PHP+Swoole 作为网络通信框架

这里瞅瞅Swoole框架,因为说的比较屌,官网里面文档比较多https://www.swoole.com/代码地址(https://gitee.com/swoole/swoole)这里先复制他的说明(https://wiki.swoole.com/)Swoole底层内置了异步非阻塞、多线程的网络IO服务器。PHP程序员仅需处理事件回调…

三角形外接球万能公式_外接球半径常见的求法

2:若一个多面体的各面都与一个球的球面相切,则称这个多面体是这个球的外切多面体,这个球是这个多面体的内切球。球心到截面的距离d与球半径R及截面的半径r有以下关系:.球面被经过球心的平面截得的圆叫.被不…

如何准备考试

最近准备International Requirement Engeering Board 考试,但凡上点年纪对记忆就不行了,时间也不够,就想着怎么偷懒。 因此,就把测试题做了一遍,然后分析各个章节的分值比重及自己容易错的地方的比重。然后有的放矢再去…

LeetCode 1676. 二叉树的最近公共祖先 IV

文章目录1. 题目2. 解题1. 题目 给定一棵二叉树的根节点 root 和 TreeNode 类对象的数组(列表) nodes,返回 nodes 中所有节点的最近公共祖先(LCA)。 数组(列表)中所有节点都存在于该二叉树中&a…

matlab行人检测非极大值抑制,多目标检测中的非极大值抑制(NMS)的算法改进_jza...

非极大值抑制(Non-Maximum Suppression,NMS),顾名思义就是抑制不是极大值的元素,可以理解为局部最大搜索。这个局部代表的是一个邻域,邻域有两个参数可变,一是邻域的维数,二是邻域的大小。而是用于目标检测…

android 粘性view_Android自定义StickinessView粘性滑动效果

design包的出现,Android界面发生了巨大变化,各种滑动配合的效果,下面我就粘性滑动中的一种进行自定义,效果图如下:大家看到效果了,这里我是继承了LinerLayout,方便一点,若果是ViewGr…

Azure SQL 数据库:服务级别与性能问答

ShawnBice 2014 年 5 月 5 日上午 10:00 几天前,我发表了一篇文章,并就 4 月 24 日发布的适用于Windows Azure SQL 数据库的新服务级别提供了一些预料中的问题和解答,在其中为读者介绍了一些详细信息。在这篇跟进文章中,我想提…

matlab粒子图像测速工具,程序 PIVlab - 时间分辨粒子图像测速(PIV)工具: 一 联合开发网 - pudn.com...

程序所属分类:图形图像处理开发工具:matlab文件大小:7964KB下载次数:29上传日期:2017-07-21 11:48:16上 传 者:long1219说明: PIVlab - 时间分辨粒子图像测速(PIV)工具:一种基于GUI…

LeetCode 1852. 每个子数组的数字种类数(滑窗)

文章目录1. 题目2. 解题1. 题目 给你一个整数数组 nums与一个整数 k,请你构造一个长度 n-k1 的数组 ans,这个数组第i个元素 ans[i] 是每个长度为k的子数组 nums[i:ik-1] [nums[i], nums[i1], ..., nums[ik-1]]中数字的种类数。 返回这个数组 ans。 示…

python读文件出现特殊字符_python- pandas :读取列中带有特殊字符的文件

添加参数na_values ’?’到read_csv.样品:import pandas as pdimport iotempu"""Date Time,a2010-01-27 16:00:00,?2010-01-27 16:10:00,2.22010-01-27 16:30:00,1.7"""df pd.read_csv(io.StringIO(temp),na_values?)p…

娜塔莉波特曼2015哈佛毕业演讲

Hello, class of 2015.I am so honest to be here today.Dean Khurana,faculty,parents,and most especially graduating students. Thank you so much for inviting me. The Senior Class Committee. it’s genuinely one of the most exciting things I’ve ever been asked …

PHP ajax 传递中文乱码,ajax+php传递中文乱码解决办法

AJAX的乱码的出现在的原因由于XMLHTTP采用的是Unicode编码上传数据,而一般页面采用的是gb2312,这就造成显示页面时产生乱码。而当在获取页面时的XMLHttp返回的是utf-8编码,这就造成了显示产生乱码。解决方法之一就是在PHP文件中显示声明为GB2312header(&…

用chrome模拟微信浏览器访问需要OAuth2.0网页授权的页面

现在很流行微信网页小游戏,用html5制作的小游戏移过来,可以放到微信浏览器中打开,关键是可以做成微信分享朋友圈的形式,大大提高游戏的传播,增强好友的游戏互动。 微信浏览器中打开网页游戏效果还不错,对手…

LeetCode 1891. 割绳子(二分查找)

文章目录1. 题目2. 解题1. 题目 给定一个整数数组 ribbons 和一个整数 k,数组每项 ribbons[i] 表示第 i 条绳子的长度。 对于每条绳子,你可以将任意切割成一系列长度为正整数的部分,或者选择不进行切割。 例如,如果给你一条长度…

公需科目必须学吗_专业技术人员一般公需科目学习的通知

根据浙江省人力资源和社会保障厅《浙江省专业技术人员继续教育学时管理办法(试行)》(浙人社发〔2016〕63号)精神,专业技术人员每年度应参加继续教育不得少于90学时,其中专业科目不少于60学时,行业公需和一般公需科目不少于18学时。现将专业技…

php.ini开启命名空间,Zend Framework教程之模型Model基本规则和使用方法

本文实例讲述了Zend Framework教程之模型Model基本规则和使用方法。分享给大家供大家参考,具体如下:这里讲讲Zend中的model。其实Zend中的Model处理是相当简单的。这主要得益于autoload功能。不像其它框架,为model定义复杂的基类。如果要定义…

LeetCode 1618. 找出适应屏幕的最大字号(二分查找)

文章目录1. 题目2. 解题1. 题目 给定一个字符串 text。并能够在 宽为 w 高为 h 的屏幕上显示该文本。 字体数组中包含按升序排列的可用字号,您可以从该数组中选择任何字体大小。 您可以使用FontInfo接口来获取任何可用字体大小的任何字符的宽度和高度。 FontInf…

UML类图画法及类之间几种关系

文章目录如下: 一、类图画法 二、类之间的几种关系:泛化(Generalization)、实现(Realization)、关联(Association)(又分一般关联、聚合(Aggregation&#xff…

web前端知识点太多_web前端常见知识点

csstable布局的缺点1、Table要比其它html标记占更多的字节。(延迟下载时间,占用服务器更多的流量资源。)2、Tablle会阻挡浏览器渲染引擎的渲染顺序。(会延迟页面的生成速度,让用户等待更久的时间。)3、Table里显示图片时需要你把单个、有逻辑性的图片切成…