【问题标题】:Compressing a list of integers for search access压缩整数列表以进行搜索访问
【发布时间】:2020-01-03 06:17:26
【问题描述】:

我有一个前缀到行的映射,看起来像这样:

{
    "x":   [9],
    "far": [1,2,3,4,5],
    "car": [1,4,5]
}

键是索引搜索词,数组是匹配的行的排序列表。很简单,一个基本的倒排索引。对于这个问题,我们假设 a-z0-9 字符的最大长度为三个 字符(上限或 36+(36^2)+(36^3)=47,988 个组合,虽然在实践中可能要少得多,比如说大约 10k 个组合)。

但是,棘手的部分是我可能有大约 1000 万行,而低基数项目可能有一个包含所有 1000 万行的(无意义的)列表。在我的计算中,一个 10M 行的数组本身在未压缩时为 88.9MB。

压缩这些经常重复的数组的建议方法是什么?看来这在搜索中一定很常见,我想了解更多关于处理大型和重复前缀映射的最佳方法,例如上面的。

【问题讨论】:

  • 你能把“所有行”的情况特殊化吗?
  • @user202729 我想是这样 - 那将如何完成? “所有行”与“无行”有何不同?例如,如果在搜索中只返回了一行而不是返回了一行,该怎么办?
  • @MattTimmermans -- 感谢您的链接。在上述情况下,我可以研究在上述情况下使用开源 (C/C++) 中的任何已知算法/结构吗?
  • 不知道 C/C++ 实现,但任何全文搜索引擎都会使用类似的东西来发布帖子列表。在 Java 中,我建议从 Elastic Search 中窃取一个。

标签: c algorithm search compression inverted-index


【解决方案1】:

我会推荐使用类似 Roaring Bitmaps 的东西(在 paper 中描述)。在 Python、Java 和 C 中都有实现,它们会自动在 3 种不同格式之间切换以实现最佳存储密度。如果你想自己实现类似的东西,它基本上结合了:

  1. 数组(默认)
  2. Bitsets(适用于更密集的集合)
  3. 运行长度编码(存储连续数字的每个“运行”的开始以及该运行的长度)

该概念适用于 32 位无符号整数,它可以轻松地包含 10M 行的信息,而无需任何额外的工作来定制您自己的解决方案。

【讨论】:

  • 感谢这些建议,这当然是可能的。两点:(1)使用这样的东西怎么样:github.com/lemire/SIMDCompressionAndIntersection(也与您的上述论文的作者相同)?那和像 RoaringBitmaps 这样的东西有什么区别? (2) 有一篇关于搜索的类似博客文章blog.algolia.com/…,并且在 cmets 中提到 Roaring Bitmaps 不适合他们的应用程序。为什么不呢?为答案干杯!
  • (1) 我认为简短的回答是这将是一个不错的选择!如果您查看该链接中引用的db.ucsd.edu/wp-content/uploads/2017/03/sidm338-wangA.pdf 的结论,它表明咆哮做出了一些权衡,但总体上并不比使用 SIMD 的排序列表压缩方法更好或更差 (2) 似乎它们有不同的用途案子?他们经常更新他们的索引,使用大约 100 GB 的存储空间,他们的数据结构使得他们的绝大多数列表都是稀疏的。它们不压缩,因此可以足够快地更新索引以进行实时更新
猜你喜欢
  • 2015-05-05
  • 1970-01-01
  • 2015-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-24
相关资源
最近更新 更多