倒排索引的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 ...
随机推荐
- 康复计划#5 Matrix-Tree定理(生成树计数)的另类证明和简单拓展
本篇口胡写给我自己这样的什么都乱证一通的口胡选手 以及那些刚学Matrix-Tree,大致理解了常见的证明但还想看看有什么简单拓展的人- 大概讲一下我自己对Matrix-Tree定理的一些理解.常见版 ...
- Linux 搭建Zookeeper集群
1.使用root创建zookeeper用户: useradd zookeeper: passwd zookeeper; 2.登录zookeeper用户,将下载的zookeeper-3 ...
- 用DapperExtensions和反射来实现一个通用搜索
前言 搜索功能是一个很常用的功能,当然这个搜索不是指全文检索,是指网站的后台管理系统或ERP系统列表的搜索功能.常见做法一般就是在搜索栏上加上几个常用字段来搜索.代码可能一般这样实现 StringBu ...
- Git基础教程(一)
本教程为学习笔记,github作为最受欢迎的资源库,不可不学!详细教程参见:廖雪峰的官方网站Git教程系列.准备花两篇幅搞定实战总结,闲言碎语少说,脚踏实地求真! 1,Git入门 Git是 ...
- spring-framework-reference阅读笔记(一)
Spring Framework Runtime 首先需要对Spring FrameWok框架有个直观的认识 Java日志框架的发展史 在读到Spring依赖JCL的时候,对Java的日志系统做点普及 ...
- Java面试13|算法
1.冒泡排序 for(int i=0;i<n;i++){ for(int j=0;j<n-1-i;j++){ if(temp[j]>temp[j+1]){ int t=temp[j] ...
- Fraction to Recurring Decimal leetcode
Given two integers representing the numerator and denominator of a fraction, return the fraction in ...
- Search a 2D Matrix leetcode
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...
- C#编写代码:求三个数中的最大数
static void Main(string[] args) { float x, y, z, temp; Console.Write(&q ...
- rsync (windows 服务端,linux客户端)将windows上的数据同步到linux服务器,反之也可
一:总体概述. 1.windows上面首先装CW_rsync_Server.4.1.0_installer,安装时要输入的用户名密码要记住哦!接下来就是找到rsyncd.conf进入配置细节 2.li ...