倒排索引

elasticsearch 基本概念

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-02 16:56:48
elasticsearch 基本概念 基本概念 elasticsearch是面向文档 关系行数据库 和 elasticsearch 客观的对比 Relational DB Elasticsearch 数据库(database) 索引(indices) 表(tables) types 行(rows) documents 字段(columns) fields elasticsearch(集群)中可以包含多个索引(数据库),每个索引中可以包含多个类型(表),每个类型下又包含多 个文档(行),每个文档中又包含多个字段(列)。 物理设计,elasticsearch 在后台把每个 索引划分成多个分片 ,每分分片可以在集群中的不同服务器间迁移 注意 elasticsearch 在第一个版本的开始 每个文档都储存在一个索引中,并分配一个 映射类型,映射类型用于表示被索引的文档或者实体的类型,这样带来了一些问题 (详情: https://www.cnblogs.com/Neeo/articles/10393961.html#important)导致后来在 elasticsearch6.0.0 版本中一个文档只能包含一个映射类型,而在 7.0.0 中,映 射类型则将被弃用,到了 8.0.0 中则将完全被删除。 逻辑设计:文档、类型、索引 一个索引类型中,包含多个文档,比如说文档1,文档2。

倒排索引结构

不羁岁月 提交于 2019-12-02 16:15:45
solr中文搜索倒排索引和数据存储结构 solr中文索引倒排索引和数据存储结构 传统的方式(正排索引)是从关键点出发,然后再通过关键点找到关键点代表的信息中能够满足搜索条件的特定信息,既通过KEY寻找VALUE。而Lucene的搜索则是采用了倒排索引的方式,即通过VALUE找KEY。而在中文全文搜索中VALUE就是我们要搜索的单词,存放所有单词的地方叫词典。KEY是文档标号列表(通过文档标号列表我们可以找到出现过要搜索单词VALUE的文档) 正排索引从文档编号找词: 倒排索引是从词找文档编号: 当文档数据来临时,solr会首先对文档数据进行分词,创建索引库和文档数据库。所谓的分词是指:将一段字符文索引本按照一定的规则分成若干个单词。如下面两篇文档通过solr后如何产生分词存储: 文章中的标点符号可以直接过滤掉,像and、too可以直接过滤掉。形成的分词表表示: Lucene的倒排索引存储结构为:词项的字符串+词项的文档频率+记录词项的频率信息+记录词项的位置信息+跳跃偏移量。简单的理解可以形成以下结构: 分别表示词,词出现的文档编号,文档中出现的频率和文档中出现的位置。这样当我们对词进行搜索时,会找到该词出现过的所有文档的ID,然后再通过该文档的ID寻找文档的具体内容。 当然,Lucene词典中词的顺序是按照英文字母的顺序排列的,这样就可以采用压缩存储:假设有term

谈谈lucene倒排索引的存储方式(一)

这一生的挚爱 提交于 2019-12-02 07:48:39
lucene的倒排索引存储包括词的索引数据存储、词的位置存储以及写入过程,这3个部分是比较复杂的准备分开描述,先谈谈位置的存储方式: 词的位置具体包括每篇文档中的词频、位置以及附带的payload(这里先忽略掉norm信息的存储),这3块lucene分别采用了3个输出流进行写入,具体写入过程如下: 1、对于每个词而言会记录该次所属的文档ID以及在该文档中的词频,由于文档ID已经排过序所以写入时会进行差值压缩存储,而文档词频会直接存储,并且每128条记录进行分块压缩存储; 2、令Doc=abc|123;bcd;def,每写完所属文档ID以及词频,就会写入该词在文档中的每个位置(指文档经过分词后的第n个词(分号为词的分隔符 def为第3个词 ))、起始和结束的偏移量( 指文档未分词时的开始和结束位置(bcd的开始和结束位置分别为8和11),通过偏移量可以算出词、payload以及payload分隔符的总长度,所以这个长度不要认为是词的长度和payload的长度(123为payload,对于abc的开始和结束位置分别为0和7) )、每个词附带的payload信息。由于位置信息、偏移量已经排过序所以会按照差值压缩存储。位置信息会按照128条记录分块压缩存储到单独的文件中

谈谈lucene倒排索引的存储方式(3-1)

坚强是说给别人听的谎言 提交于 2019-12-02 07:48:15
现在开启lucene倒排索引之词的索引存储之旅也就是对BlockTreeTermsWriter类分析,这是lucene中难啃的骨头之一,为了方便记忆和理解,还有保持内容的跟进,先准备对着代码一步步描述,而前面所有关于lucene的内容都是看完代码再总结的,因此可以想象这块内容的复杂度。 当写入一个词的时候会先写入该词的posting,然后将再写入返回的posting状态信息和词本身。posting的写入过程在 谈谈lucene倒排索引的存储方式 (一)和(二)中已经说明。 假设minItemsInBlock=3,根据下面的代码 当输入abc时: prefixStarts=[0,0,0] pendingSize=1; 当输入abcd时: prefixStarts=[0,0,0,1] pendingSize=2; 当输入abcde时: prefixStarts=[0,0,0,1,2] pendingSize=3; 当输入abe时: prefixStarts 从理应的[0, 0, 3, 1, 2]变成[0, 0, 1, 1, 2] pendingSize=4; 如果只看输入abe时prefixStarts=[0, 0, 3, 1, 2],从输入abc时prefixStarts的变化情况,结合prefixTopSize可以看出prefixStarts下标记录的是公共前缀的长度

谈谈lucene倒排索引的存储方式(3-3)

这一生的挚爱 提交于 2019-12-02 07:48:00
通过 谈谈lucene倒排索引的存储方式(3-2) 和 谈谈lucene倒排索引的存储方式(3-1) 的分析可知,当有公共前缀的词的数量达到指定阈值时会写入到一个Block中,不过还没有对其中的细节进行分析,现通过给定的输入abc、abcd、abcde、abcdef、abcdf、abcdg、abe、abf、abg、abh,以及参数阈值MIN_BLOCK_SIZE = 3和MAX_BLOCK_SIZE = 4来对倒排索引的构成进一步研究。 当输入abe时由于abcd、abcde、abcdef、abcdf、abcdg以abcd为前缀的个数为5个已经超过MIN_BLOCK_SIZE个数,因此达到写成一个Block的条件,由于MAX_BLOCK_SIZE=4所以对这5个item需要进一步按照MIN_BLOCK_SIZE3个为一组进行拆分,即abcd、abcde、abcdef会写到一个Block( 该Block也是一个leafBlock,因为它的元素只有词 )中,除了前缀abcd,其余的后缀以及postings元数据(经过压缩)会全部写入到termsOut文件流中,对于该Block有以下重要属性prefix, startFP, hasTerms, isFloor, floorLeadLabel, subIndices,其中prefix表示公共前缀即abcd

[转帖]时序数据库技术体系 – InfluxDB TSM存储引擎之数据读取

允我心安 提交于 2019-12-01 10:19:35
时序数据库技术体系 – InfluxDB TSM存储引擎之数据读取 http://hbasefly.com/2018/05/02/timeseries-database-7/ 2018年5月2日 范欣欣 时序数据库 任何一个数据库系统内核关注的重点无非:数据在内存中如何存储、在文件中如何存储、索引结构如何存储、数据写入流程以及数据读取流程。关于InfluxDB存储内核,笔者在之前的文章中已经比较全面的介绍了数据的文件存储格式、倒排索引存储实现以及数据写入流程,本篇文章重点介绍InfluxDB中时序数据的读取流程。 InfluxDB支持类SQL查询,称为InfluxQL。InfluxQL支持基本的DDL操作和DML操作语句,详见 InfluxQL_Spec ,比如Select语句: select_stmt = "SELECT" fields from_clause [ into_clause ] [ where_clause ] [ group_by_clause ] [ order_by_clause ] [ limit_clause ] [ offset_clause ] [ slimit_clause ] [ soffset_clause ] . 使用InfluxQL可以非常方便、人性化地对InfluxDB中的时序数据进行多维聚合分析

[转帖]时序数据库技术体系 – InfluxDB TSM存储引擎之数据写入

女生的网名这么多〃 提交于 2019-12-01 10:19:34
时序数据库技术体系 – InfluxDB TSM存储引擎之数据写入 http://hbasefly.com/2018/03/27/timeseries-database-6/ 2018年3月27日 范欣欣 时序数据库 之前两篇文章笔者分别从TSM File文件存储格式、倒排索引文件存储格式这两个方面对InfluxDB最基础、最底层也最核心的存储模块进行了介绍,接下来笔者会再用两篇文章在存储文件的基础上分别介绍InfluxDB是如何处理用户的写入(删除)请求和读取请求的。在阅读这两篇文章之前,强烈建议看官先行阅读之前的多篇文章,不然可能会有一定的阅读障碍。 InfluxDB写入总体框架 InfluxDB提供了多种接口协议供外部应用写入,比如可以使用collected采集数据上传,可以使用opentsdb作为输入,也可以使用http协议以及udp协议批量写入数据。批量数据进入到InfluxDB之后总体会经过三个步骤的处理,如下图所示: 批量时序数据shard路由:InfluxDB首先会将这些数据根据shard的不同分成不同的分组,每个分组的时序数据会发送到对应的shard。每个shard相当于HBase中region的概念,是InfluxDB中处理用户读写请求的单机引擎。 倒排索引引擎构建倒排索引:InfluxDB中shard由两个LSM引擎构成 – 倒排索引引擎和TSM引擎

谈谈lucene倒排索引的存储方式(二)

元气小坏坏 提交于 2019-12-01 03:56:44
在 谈谈lucene倒排索引的存储方式(一) 中只说明了倒排索引位置相关信息的存储,并没有详细说明如果需要对位置信息进行随机访问,那么它的索引该如何设计。lucene采用的是多级跳跃链表的方式,先说说跳跃链表基本思想(其实在前面文中也提过),假设给定一堆排过序的数字,并且数据量很大以至于在内存中放不下,如果要快速随机访问其中的某个数值,一种方法是对这些数字每隔一定的条数如1000条就记录相应的数值以及对应的文件指针,然后把这些数值以及对应的文件指针加载到内存中采用二分查找法找到欲查找数值所在数据块的起始地址,然后将1000条记录依次遍历比较或者加载到内存中采用二分查找都可以,这些数值和文件指针又叫一级跳跃表。 如果说一级跳跃表的数据量依然很大,那么又要在此基础上再建立一层跳跃表,依此类推就会有多级跳跃表了。值得一提的是级数并不是越多越好,因为层级越多,查找的次数也越多,lucene默认最大层级为10。 上图是lucene官方给出的示图(一个词代表的倒排位置索引),d代表文档,x代表每隔128个文档进行压缩的文件指针也是第一层级的索引记录了相应的文档ID和所在文件的指针,c分别为第二层级和第三层级。这样感觉在代码实现上较复杂的索引结构确在lucene实现的时候显得非常讨巧,因为总的层级可以预先算出来,然后可以边写边计算出文档所在层级。有兴趣滴还是看代码吧。 来源: oschina

谈谈lucene倒排索引的存储方式(3-3)

做~自己de王妃 提交于 2019-11-30 17:57:31
通过 谈谈lucene倒排索引的存储方式(3-2) 和 谈谈lucene倒排索引的存储方式(3-1) 的分析可知,当有公共前缀的词的数量达到指定阈值时会写入到一个Block中,不过还没有对其中的细节进行分析,现通过给定的输入abc、abcd、abcde、abcdef、abcdf、abcdg、abe、abf、abg、abh,以及参数阈值MIN_BLOCK_SIZE = 3和MAX_BLOCK_SIZE = 4来对倒排索引的构成进一步研究。 当输入abe时由于abcd、abcde、abcdef、abcdf、abcdg以abcd为前缀的个数为5个已经超过MIN_BLOCK_SIZE个数,因此达到写成一个Block的条件,由于MAX_BLOCK_SIZE=4所以对这5个item需要进一步按照MIN_BLOCK_SIZE3个为一组进行拆分,即abcd、abcde、abcdef会写到一个Block( 该Block也是一个leafBlock,因为它的元素只有词 )中,除了前缀abcd,其余的后缀以及postings元数据(经过压缩)会全部写入到termsOut文件流中,对于该Block有以下重要属性prefix, startFP, hasTerms, isFloor, floorLeadLabel, subIndices,其中prefix表示公共前缀即abcd

谈谈lucene倒排索引的存储方式(3-1)

走远了吗. 提交于 2019-11-30 16:59:27
现在开启lucene倒排索引之词的索引存储之旅也就是对BlockTreeTermsWriter类分析,这是lucene中难啃的骨头之一,为了方便记忆和理解,还有保持内容的跟进,先准备对着代码一步步描述,而前面所有关于lucene的内容都是看完代码再总结的,因此可以想象这块内容的复杂度。 当写入一个词的时候会先写入该词的posting,然后将再写入返回的posting状态信息和词本身。posting的写入过程在 谈谈lucene倒排索引的存储方式 (一)和(二)中已经说明。 假设minItemsInBlock=3,根据下面的代码 当输入abc时: prefixStarts=[0,0,0] pendingSize=1; 当输入abcd时: prefixStarts=[0,0,0,1] pendingSize=2; 当输入abcde时: prefixStarts=[0,0,0,1,2] pendingSize=3; 当输入abe时: prefixStarts 从理应的[0, 0, 3, 1, 2]变成[0, 0, 1, 1, 2] pendingSize=4; 如果只看输入abe时prefixStarts=[0, 0, 3, 1, 2],从输入abc时prefixStarts的变化情况,结合prefixTopSize可以看出prefixStarts下标记录的是公共前缀的长度