这是一道来自百度的面试题。倒排索引的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. Struts2之访问路径

    上一篇已经和大家分享了关于Struts2命名空间和Action的三种创建方式,本篇我们接着命名空间的内容,来一起探讨一下关于Struts2的访问路径问题,何为访问路径,就是指当我们在浏览器输入地址,点 ...

  2. Unbutu14.04 启用 root 并禁用guest

    系统环境: Ubuntu14.04 x64 问题描述: Ubuntu14.04的64位系统默认禁用 root 账号登录 解决方式:            1. 为root设置密码 sudo passw ...

  3. gulp折腾日记——gulp-livereload

    大家好,虽然在博客园注册了很长一段时间,但我还没在博客园写过博客,这是在博客园的第一篇博客,希望能养成每周写博客的好习惯 O(∩∩)O~~) 今天要聊得是gulp的一个实时刷新的插件gulp-live ...

  4. 学习HTML5一周的收获4

    /* [CSS常用文本属性]  * 1.字体.字号: font-weight:字体的粗细,可选属性值:bold加粗  lighter细体  100~900数值(400正常,700 bold)   fo ...

  5. Asp.net MVC 视图使用像Ajax,ViewBag提示为找到上下文

    不知是什么原因,所有的视图中Ajax,ViewBag之类的都提示为找到上下文(由于换了个版本Vs,猜测应该是Vs的原因),然后顺利在网上找到了解决方案. 给地址链接:https://social.ms ...

  6. 1619: [Usaco2008 Nov]Guarding the Farm 保卫牧场

    1619: [Usaco2008 Nov]Guarding the Farm 保卫牧场 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 498  Solve ...

  7. webpack和webpack-dev-server安装配置(遇到各种问题的解决方法)

    跟着Webpack傻瓜式指南(一)这个教程在安装webpack和webpack-dev-server的时候遇到很多问题,查了很多终于一一找到解决办法. 主要参考了这三篇博文: moudule.js:3 ...

  8. supermap开发webgis的经验

    SuperMap 开发WebGIS的经验总结 - 综合课件 - 道客巴巴 http://www.doc88.com/p-743552004620.html

  9. Java开发过程中开发工具Eclipse中导入jar包的过程

    欢迎欣赏我的第二篇随笔.我们在创建好一个动态网站项目之后,如果没有部署maven的情况下,你可以按照以下的方法,直接把要用的jar包导入你的工程中,而不用再部署maven. 例如在使用JDBC编程时需 ...

  10. java学习笔记----运算符

    一.算数运算符 特别说明: 加 ,减 ,乘 ,除 与数学运算一致 取余符号看被除数 自加(减)运算:++a,--a;先做自加(自减)运算在做其他运算 a++,a--;先做其他运算在做自加(自减)运算 ...