Algorithm 比特掩码与bloom过滤器
我正在寻找使用bloom过滤器或位掩码预过滤搜索结果。举一个具体的例子:Algorithm 比特掩码与bloom过滤器,algorithm,search,optimization,bitmask,bloom-filter,Algorithm,Search,Optimization,Bitmask,Bloom Filter,我正在寻找使用bloom过滤器或位掩码预过滤搜索结果。举一个具体的例子: id,product,description 1,"coke", "A popular soft drink since 1900" 2,"pepsi", "A popular soda, similar to coke" 3,"soda", "A word to describe various soft drinks" 如果用户搜索“coke”一词,我们将在product=“coke”上匹配第1行和descripti
id,product,description
1,"coke", "A popular soft drink since 1900"
2,"pepsi", "A popular soda, similar to coke"
3,"soda", "A word to describe various soft drinks"
如果用户搜索“coke”一词,我们将在product=“coke”
上匹配第1行和description(has word)=“coke”
我们有内存限制,所以不能索引太多的项,但我正在考虑根据每行包含的第一个字母实现一个位掩码。这样,我们可以看到c
包含在第1行和第2行中,但不包含在第3行中,因此我们根本不会在搜索中包含它
如果我们取前三行,“单词以开头”掩码看起来像(对于字母表的前三个字母)——
那么,我的问题有两个:
- 对于上面这样的场景,使用bloom过滤器是否比使用位掩码更有优势?为什么?(我对布卢姆过滤器不太熟悉,自己也从未使用过)
- 上面的一个字母的位掩码看起来有用吗,还是看起来它实际上不能解决任何问题(例如,每行只能有一个字符
)a=1
- 是否有针对常见字母/单词的建议方法。例如,“a/an”、“the”等似乎会出现在几乎所有具有自然文本的列中
有关搜索要求的更多详细信息:
- 最大数据大小为1GB。这将根据行的大小转换为1M-10M行之间的任何位置
- 这里几乎没有额外的可用空间,所以像传统索引这样的东西是不可能的。作为参考,假设任何数据集上都有10%的空间来存储辅助信息,例如位掩码/过滤器/索引等
- 两个示例查询是
(完全内部搜索)或description,如“%drink%”
(“边缘搜索”,在任何单词的开头搜索)description REGEXP'^ |\sdrink'
这个问题涉及面很广,所以我只给出了几点建议供大家阅读。希望您能发现它们有用。您的位掩码是简单的Bloom过滤器:假设您关心26个可能的字符,即使用
m=26*rowCount
、k=1
,以及以下哈希函数:hash(firstLetter,rowId)=(firstLetter*rowCount+rowId)
。这很容易实现,但可能不是很有效,因为一些字母经常出现(例如字符“e”)。您的位掩码每行大约需要4个字节,这可能还可以。对于每一行,您都执行Bloom筛选器查找
最好使用更复杂的布卢姆过滤器。它看起来如何完全取决于您拥有的数据。假设您使用m=26*rowCount
,k=1
和hash(firstLetter,secondLetter,rowId)=((11*firstLetter+113*secondLetter)模26)*rowCount+rowId)
。这样,它使用相同的空间,但位的分布更加均匀。对于频繁的信件,这大大加快了搜索速度,但代价是搜索频率较低的信件的速度稍慢
更好的方法可能是组合多行,假设每个行组合8行(行0..7,8..15,…),然后在Bloom筛选器中设置所需的所有位。这样,您可以大大减少查找的数量
如果您的查询可以是
形式,如“%drink%”
,那么只查看前几个字符的过滤器就没有用处:您仍然需要进行完整扫描。相反,您可以有一个Bloom过滤器,它组合(比如)8行,并设置每个字符对的所有位。也就是说,['dr','ri','in','nk']
,并使用m=26*rowCount/8
,k=1
,和hash(firstLetter,secondLetter,rowGroup)=((11*firstLetter+113*secondLetter)模26)*rowCount 8+rowGroup),以及
rowGroup=rowId/8`。因此,基本上检查字符对是否出现在某个行组中。这样,您甚至可以对“like”条件和正则表达式使用Bloom过滤器。Bloom过滤器很酷,我很乐意分享一下我们为产品功能所做的实现细节。但是这里有一个主要的问题-你的内存限制是什么,你实际会有多少个条目,以及每个产品/描述字符串的平均大小?您还需要实现一个分词算法…@selbie cool——数据大小可能约为800MB/几百万行,并且我们没有太多空间来存储额外的数据结构(我想说10%的空间)。目前,我们的分词出现在空格/标签上有几个单独的原因(一个人可以输入带有破折号/斜杠的日期,以及其他一些奇怪的事情)。你的bitmask是一个带有非常糟糕哈希的Bloom过滤器function@MattTimmermans为什么在这种情况下需要一个散列函数(或者不需要?)如何使用位掩码(在一个字母上)不节省空间,我不明白?一个32位掩码将每行存储一个额外的整数?对不起,我想说的是时间效率。编辑了答案。当你说“这没有时间效率”时,你能澄清一下你的意思吗?在执行逐位运算时,它不会变得更快(我知道?),或者你的确切意思是什么?在第一个
a b c d
1 0 1 1 (row 1 -- coke) -- has c? Y
1 0 1 0 (row 2 -- pepsi) -- has c? Y
1 0 0 1 (row 3 -- soda) -- has c? NO -- SKIP