这是一道来自百度的面试题。倒排索引的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操作的更多相关文章

  1. 学习笔记:The Log(我所读过的最好的一篇分布式技术文章)

    前言 这是一篇学习笔记. 学习的材料来自Jay Kreps的一篇讲Log的博文. 原文很长,但是我坚持看完了,收获颇多,也深深为Jay哥的技术能力.架构能力和对于分布式系统的理解之深刻所折服.同时也因 ...

  2. 学习笔记:The Log(我所读过的最好的一篇分布式技术文章)

    前言 这是一篇学习笔记. 学习的材料来自Jay Kreps的一篇讲Log的博文. 原文非常长.可是我坚持看完了,收获颇多,也深深为Jay哥的技术能力.架构能力和对于分布式系统的理解之深刻所折服.同一时 ...

  3. 搜索引擎框架之ElasticSearch基础详解(非原创)

    文章大纲 一.搜索引擎框架基础介绍二.ElasticSearch的简介三.ElasticSearch安装(Windows版本)四.ElasticSearch操作客户端工具--Kibana五.ES的常用 ...

  4. Es图形化软件使用之ElasticSearch-head、Kibana,Elasticsearch之-倒排索引操作、映射管理、文档增删改查

    今日内容概要 ElasticSearch之-ElasticSearch-head ElasticSearch之-安装Kibana Elasticsearch之-倒排索引 Elasticsearch之- ...

  5. Hadoop之倒排索引

    前言: 从IT跨度到DT,如今的数据每天都在海量的增长.面对如此巨大的数据,如何能让搜索引擎更好的工作呢?本文作为Hadoop系列的第二篇,将介绍分布式情况下搜索引擎的基础实现,即“倒排索引”. 1. ...

  6. [Search Engine] 搜索引擎技术之倒排索引

    倒排索引是搜索引擎中最为核心的一项技术之一,可以说是搜索引擎的基石.可以说正是有了倒排索引技术,搜索引擎才能有效率的进行数据库查找.删除等操作. 1. 倒排索引的思想 倒排索引源于实际应用中需要根据属 ...

  7. elasticsearch使用操作部分

    本片文章记录了elasticsearch概念.特点.集群.插件.API使用方法. 1.elasticsearch的概念及特点.概念:elasticsearch是一个基于lucene的搜索服务器.luc ...

  8. lucene倒排索引缓冲池的细节

    倒排索引要存哪些信息   提到倒排索引,第一感觉是词到文档列表的映射,实际上,倒排索引需要存储的信息不止词和文档列表.为了使用余弦相似度计算搜索词和文档的相似度,需要计算文档中每个词的TF-IDF值, ...

  9. Elasticsearch1.7服务搭建与入门操作

    ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java开发的,并作为Apach ...

随机推荐

  1. Cloudera Manager安装_搭建CDH集群

    2017年2月22日, 星期三 Cloudera Manager安装_搭建CDH集群 cpu   内存16G 内存12G 内存8G 默认单核单线 CDH1_node9 Server  || Agent ...

  2. 一个基于Behave框架的http接口测试实例

    前言:本人没怎么做过http接口测试,只是最近学习了一下,Behave框架也是最近学习的,如果有不对的请各位大神指点,感谢! 1.1       接口准备 本次get请求的接口用的是百度接口:wd=搜 ...

  3. JS中的onclick事件

    原文链接:https://segmentfault.com/q/1010000007955542?_ea=1503986 我自己做了一下测试. 这个是在html里面直接绑定onclick事件,我打印了 ...

  4. Ubuntu下安装Redis并实现远程访问

    之前的一篇随笔写到Redis在Windows下的安装,但目前好多大数据处理的服务是在Linux上的,所以想以Redis为例并实现在Windows上利用C#代码远程访问. 以在Ubuntu下为例,步骤如 ...

  5. Asp.Net 常用工具类之Office—Excel导出(4)

    开发过程中各类报表导入导出防不胜防,网上也是各种解决方法层出不穷,比如Excel,CSV,Word,PDF,HTML等等... 网上各种导出插件也是层出不穷,NPOI,微软Microsoft.Offi ...

  6. AR入门系列-07-Vuforia柱形体识别

    今天为大家带来Vuforia柱形体识别的使用教程 首先我们要进入Vuforia官网在TargetManager中添加Target,这次我们添加的类型为Cylinder圆柱 Bottom Diamete ...

  7. UVa 1588 换抵挡装置

    前言 题目 大意是说,两个槽能够插在一起,并保证每一列的高度不高于3,保证最短长度. 思路 思路很简单,取短字符串遍历长字符串的每一个位置,纪录下位置,并取最短即可. 实现 //习题3-11 换抵挡装 ...

  8. wemall开源商城免费商城系统部分代码(内含代码地址)

    wemall开源商城免费商城系统部分代码,下面分享部分代码,供学习者学习: 开源版把install文件夹下的install.lock删除之后可进行自动安装 后台访问地址:http:// www.xxx ...

  9. 关于java泛型

    <T> 代表的是泛型 ,实例化的时候将传入真正的数据类型,比如: public interface BaseProvider<T>{ public T test(); } 实例 ...

  10. Nginx uWSGI web.py 站点搭建

    一.安装nginx 在安装nginx前,需要先装nginx的依赖包. 1.如果没有yum则先安装yum   删除原有的yum  rpm -aq|grep yum|xargs rpm -e --node ...