Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 比特掩码与bloom过滤器_Algorithm_Search_Optimization_Bitmask_Bloom Filter - Fatal编程技术网

Algorithm 比特掩码与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

我正在寻找使用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行和
description(has word)=“coke”

我们有内存限制,所以不能索引太多的项,但我正在考虑根据每行包含的第一个字母实现一个位掩码。这样,我们可以看到
c
包含在第1行和第2行中,但不包含在第3行中,因此我们根本不会在搜索中包含它

如果我们取前三行,“单词以开头”掩码看起来像(对于字母表的前三个字母)——

那么,我的问题有两个:

  • 对于上面这样的场景,使用bloom过滤器是否比使用位掩码更有优势?为什么?(我对布卢姆过滤器不太熟悉,自己也从未使用过)
  • 上面的一个字母的位掩码看起来有用吗,还是看起来它实际上不能解决任何问题(例如,每行只能有一个字符
    a=1
  • 是否有针对常见字母/单词的建议方法。例如,“a/an”、“the”等似乎会出现在几乎所有具有自然文本的列中

有关搜索要求的更多详细信息:

  • 最大数据大小为1GB。这将根据行的大小转换为1M-10M行之间的任何位置
  • 这里几乎没有额外的可用空间,所以像传统索引这样的东西是不可能的。作为参考,假设任何数据集上都有10%的空间来存储辅助信息,例如位掩码/过滤器/索引等
  • 两个示例查询是
    description,如“%drink%”
    (完全内部搜索)或
    description REGEXP'^ |\sdrink'
    (“边缘搜索”,在任何单词的开头搜索)

如果您不能容忍误报,则不得使用bloom filter,因为它是一种概率数据结构

因为位掩码方法显然不具有时间效率,并且该方法很难在以后扩展。当您谈论大约800MB的数据大小时,您正在进入的是。现在的问题不再局限于“位掩码与Bloom过滤器”,只要阅读中的索引相关概念,它们可能会对您有所帮助

要解决常见单词,请阅读它们是什么以及如何删除它们。要进入下一个层次,如果你不需要找到确切的单词,请阅读和


这个问题涉及面很广,所以我只给出了几点建议供大家阅读。希望您能发现它们有用。

您的位掩码是简单的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