倒排索引是如何存储的?
How are inverted index stored?
我最近制作了一个大约的索引。内存中有 2,000,000 个文档。这些文档是从 mysql 数据库导入的,加载大约需要 6 到 10 秒。每次我启动程序时,导入数据都会消耗时间。我尝试过使用 json、pickle、cPickle 甚至 redis,但时间紧迫,为了更新,我必须重新启动整个程序。我在这里使用 python。
我的问题是google、solr、elasticsearch等搜索引擎是如何存储倒排索引的。他们是将它们作为哈希表存储在内存中还是存储在数据库中?如何在不重启的情况下更新索引?什么是用于此目的的最佳数据库。
简答:
您不需要将所有内容都加载到内存中,因为对于大型文档集合,此过程可能特别慢(更糟糕的是,倒排索引甚至可能无法容纳在内存中)。
长答案:
倒排索引通常存储在磁盘上,并根据查询动态加载...例如如果查询是 "stack overflow",则您点击了与术语 'stack' 和 'overflow'...
相对应的各个列表
倒排列表的文件结构是固定长度和可变长度组件的混合体。可变长度信息存储为 pointers.
由于术语(本质上是字符串)的长度可变,因此它们被转换为整数(4/8 字节的固定长度)。映射通常存储在内存中作为散列-table(#terms 通常不会大到 100K 的量级,很容易放入内存)。
给定一个术语,您必须在内存哈希table 上查找它并获得它的 id。然后,您使用 id 直接跳转(随机访问偏移)到它在磁盘上的位置。此位置包含指向包含该术语的文档列表的指针(此列表是可变长度的),您必须将其加载到内存中。
加载所有查询词的帖子(通常不是很多)后,您可以通过遍历这些列表(通常这些列表按文档 ID 排序)来汇总所有文档的分数。
以上描述示意图:
我最近制作了一个大约的索引。内存中有 2,000,000 个文档。这些文档是从 mysql 数据库导入的,加载大约需要 6 到 10 秒。每次我启动程序时,导入数据都会消耗时间。我尝试过使用 json、pickle、cPickle 甚至 redis,但时间紧迫,为了更新,我必须重新启动整个程序。我在这里使用 python。
我的问题是google、solr、elasticsearch等搜索引擎是如何存储倒排索引的。他们是将它们作为哈希表存储在内存中还是存储在数据库中?如何在不重启的情况下更新索引?什么是用于此目的的最佳数据库。
简答:
您不需要将所有内容都加载到内存中,因为对于大型文档集合,此过程可能特别慢(更糟糕的是,倒排索引甚至可能无法容纳在内存中)。
长答案:
倒排索引通常存储在磁盘上,并根据查询动态加载...例如如果查询是 "stack overflow",则您点击了与术语 'stack' 和 'overflow'...
相对应的各个列表倒排列表的文件结构是固定长度和可变长度组件的混合体。可变长度信息存储为 pointers.
由于术语(本质上是字符串)的长度可变,因此它们被转换为整数(4/8 字节的固定长度)。映射通常存储在内存中作为散列-table(#terms 通常不会大到 100K 的量级,很容易放入内存)。
给定一个术语,您必须在内存哈希table 上查找它并获得它的 id。然后,您使用 id 直接跳转(随机访问偏移)到它在磁盘上的位置。此位置包含指向包含该术语的文档列表的指针(此列表是可变长度的),您必须将其加载到内存中。
加载所有查询词的帖子(通常不是很多)后,您可以通过遍历这些列表(通常这些列表按文档 ID 排序)来汇总所有文档的分数。
以上描述示意图: