倒排索引的AND操作
这是一道来自百度的面试题。倒排索引的AND操作。
倒排索引是以关键词作为索引项来索引文档的一种机制,如图中Brutus、Calpurnia、Caesar为关键词,2、4、8等等为文档ID。
现在有一个查询:Brutus AND Calpurnia AND Caesar。这个查询实际上就是要找出Brutus(以下简称B)、Calpurnia(以下简称C1)和Caesar(C2)的索引文档中的相同项。假设B、C1、C2的长度分别为m、n、p。
比较容易想到的是用归并排序的思想来解决这个问题。即:对3个线性表进行归并排序并对相同项计数,计数为3的项即为结果,这个方法时间复杂度为O(m+n+p),就这个例子我们需要比较7+8+2=17次。
百度的面试题经常会问到一个问题,有没有更快的方法?答案是肯定的。
这个题目的目的只是找到计数为3的项,而不是排序结果,所以实际上,对2个表经过一次归并之后,计数小于2的项可以舍去了,这样剩下的结果再进行归并,表长度会下降,比较次数自然也就少了。自然而然的,我们会想到先把两个能生成更短结果的表进行比较。
怎样的两个表AND生成的表长度会比较短?严格判断这个问题很难,但是我们可以进行一个很简单的假设:两个长度最短的表AND结果会比较短。于是这里我们可以先将B和C1进行AND,得到结果:16。然后与C1进行AND,得到空集。需要比较4+2+7=13次。
为什么仍然需要比较这么多次呢?因为16和C1比较时,仍然需要找到21(>16)时才能知道:不需要再比较了。那么我们可不可以再缩短这个比较次数呢?答案仍是肯定的。
如下图,我们可以每隔k项建立一个skip项,保留下一个skip项的值。在比较A、B表时,如果A表当前项大于B表当前项,就可以比较A表当前项是否大于B表下一个skip项,如果大于,则B表直接跳到下一个skip项;如果小于,则依然逐个对B表的项进行比较。
还是说开始的例子,当C1表与16比较时,假设1保留了skip值,为8,则可以直接跳过3项,与8进行比较,从而减少次数到4+2+4=10次。
如何建立skip项是个问题:太密集则skip成功次数多,但是跳过的数量少,建立skip复杂度较大,比较次数变多;太稀疏则skip项跨度太大,不容易skip成功,反而徒增比较skip项次数。有人提出用sqrt(length)作为skip长度。而我认为,可以基于项的密度来做:项密度较大,如 1 2 3 4 5 6 ..100的表,可以取50个一跳;相应的,如果1 10 20 30 40 50 60 70 80 90的表,可以取7、8个一跳。当然这样因为skip长度是不等的,就需要额外开辟一个空间来存储skip项的index。但是比较次数是不会增加的,所以仍然可行,当然在构建skip项的时候会麻烦一点。但是搜索引擎更加关心如何使查询的响应时间缩短,对于文档的预处理工作的时间要求则会低一点,所以这样做也是可以的。
说完了AND,也说说OR和NOT。OR自然是线性表合并,用归并排序可以解决,可以考虑将其中AND部分排序到前面。
NOT比较麻烦。假设S为全集,对单个表A做NOT操作,则相当于S-A。但是显然不会有人只用一个NOT A进行查询,一般的查询都是X AND (NOT B)形式,实际上也就是X-B。如何求X-B?依然可以用X AND B的方法,只不过找两个表的相同项变成找两个表的不同项了。
倒排索引的AND操作的更多相关文章
- 学习笔记:The Log(我所读过的最好的一篇分布式技术文章)
前言 这是一篇学习笔记. 学习的材料来自Jay Kreps的一篇讲Log的博文. 原文很长,但是我坚持看完了,收获颇多,也深深为Jay哥的技术能力.架构能力和对于分布式系统的理解之深刻所折服.同时也因 ...
- 学习笔记:The Log(我所读过的最好的一篇分布式技术文章)
前言 这是一篇学习笔记. 学习的材料来自Jay Kreps的一篇讲Log的博文. 原文非常长.可是我坚持看完了,收获颇多,也深深为Jay哥的技术能力.架构能力和对于分布式系统的理解之深刻所折服.同一时 ...
- 搜索引擎框架之ElasticSearch基础详解(非原创)
文章大纲 一.搜索引擎框架基础介绍二.ElasticSearch的简介三.ElasticSearch安装(Windows版本)四.ElasticSearch操作客户端工具--Kibana五.ES的常用 ...
- Es图形化软件使用之ElasticSearch-head、Kibana,Elasticsearch之-倒排索引操作、映射管理、文档增删改查
今日内容概要 ElasticSearch之-ElasticSearch-head ElasticSearch之-安装Kibana Elasticsearch之-倒排索引 Elasticsearch之- ...
- Hadoop之倒排索引
前言: 从IT跨度到DT,如今的数据每天都在海量的增长.面对如此巨大的数据,如何能让搜索引擎更好的工作呢?本文作为Hadoop系列的第二篇,将介绍分布式情况下搜索引擎的基础实现,即“倒排索引”. 1. ...
- [Search Engine] 搜索引擎技术之倒排索引
倒排索引是搜索引擎中最为核心的一项技术之一,可以说是搜索引擎的基石.可以说正是有了倒排索引技术,搜索引擎才能有效率的进行数据库查找.删除等操作. 1. 倒排索引的思想 倒排索引源于实际应用中需要根据属 ...
- elasticsearch使用操作部分
本片文章记录了elasticsearch概念.特点.集群.插件.API使用方法. 1.elasticsearch的概念及特点.概念:elasticsearch是一个基于lucene的搜索服务器.luc ...
- lucene倒排索引缓冲池的细节
倒排索引要存哪些信息 提到倒排索引,第一感觉是词到文档列表的映射,实际上,倒排索引需要存储的信息不止词和文档列表.为了使用余弦相似度计算搜索词和文档的相似度,需要计算文档中每个词的TF-IDF值, ...
- Elasticsearch1.7服务搭建与入门操作
ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java开发的,并作为Apach ...
随机推荐
- 超出区域文字显示为省略号或者剪切效果——CSS的生僻操作
每门语言总有那么一些不太常用,却又不可或缺的语法操作.下面说一下,在HTML文件中,如何设置用 "省略号" 和 "剪切" 代替大量文字的效果. 以下是HTML的 ...
- 3400: [Usaco2009 Mar]Cow Frisbee Team 奶牛沙盘队
3400: [Usaco2009 Mar]Cow Frisbee Team 奶牛沙盘队 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 129 Solv ...
- java配置文件的读写
最近在做一个爬虫项目时,用到了读写配置文件的方法,记录下来以后可能用的到. Properties pro = new Properties(); boolean IsFirst = true; //从 ...
- IOS本地日志记录方案
我们在项目中日志记录这块也算是比较重要的,有时候用户程序出什么问题,光靠服务器的日志还不能准确的找到问题. 现在一般记录日志有几种方式: 1.使用第三方工具来记录日志,如腾讯的Bugly,它是只把程序 ...
- cobbler自动安装系统
一.简介 Cobbler是一个快速网络安装linux的服务,而且在经过调整也可以支持网络安装windows.该工具使用python开发,小巧轻便(才15k行python代码),使用简单的命令即可完成P ...
- C#对委托的初步理解理解
作为新手对委托的学习: 1.定义委托:委托实际上是一个类,在定义委托前就知道了方法的返回类型和方法的参数类型(可以把委托理解为只知道方法的返回类型和方法的参数类型,不知道方法体) public de ...
- 【CNMP系列】VIM编辑器详解
缘起 大学的时候做过Linux内核驱动程序研发,之前写C语言就是用的Vim编辑器,当年的Vim还不如今天之强大,当时的插件也没有现在这么多,只是觉得这个编辑器能满足我想要的所有,查看Linux内核代码 ...
- oracle数据库如何打印九九乘法表
对于九九乘法表,相信对于懂IT的人并不陌生,但是外行可能会有很多的不懂,c语言也同样需要了解,它是学习的入门课程,oracle数据库书写九九乘法表有好几种方式,下面就有我为大家介绍,一起来看看吧. 九 ...
- IOS各种手势操作实例
先看下效果 手势相关的介绍 IOS中手势操作一般是 UIGestureRecognizer 类的几个手势子类去实现,一般我们用到的手势就这么5种: 1.点击 UITapGestureRecogniz ...
- 【VB超简单入门】六、基本数据类型
接下来要介绍VB的基本数据类型,为接下来学习变量和常量准备. 计算机只能处理二进制的数据,所以无论什么数据,在CPU里面处理都是一样的,类似101010这样的机器代码,但是让我们直接去写机器代码程序, ...