我有一个拥有大约100万个姓名和地址的数据库。应该公开该数据库,以便在网页上进行“Google Suggest”式即时搜索。我正在寻找一种有效的算法/数据结构,可以帮助我实现这一目标。
使这比使用Trie或Generalized Suffix Tree更困难的是,它必须支持一些遗漏的查询。例如,当用户输入“Elvis Pr”时,应该建议“Elvis Aaron Presley”。
我希望将整个索引放在内存中(我有大约4GB的RAM用于此)。
应用程序是用Java编写的,因此链接到基于Java的库被认为是非常有用的。我一直在寻找Lucene和MG4J,但我还没弄清楚我可以使用哪种类型的索引来解决我的问题。
答案 0 :(得分:2)
也许您真正想要的是一种搜索,其中用户键入的每个单词必须显示为联系人中某个单词的前缀。这比一般子字符串搜索更容易,更快。
答案 1 :(得分:1)
您可以尝试使用带有字符串距离指标的bk-tree,例如levenshtein,另请参阅http://blog.notdot.net/2007/4/Damn-Cool-Algorithms-Part-1-BK-Trees。
修改强> 发明距离度量很难,但我碰巧知道一个可以使用的名为structural entropic distance的基于信息差异的文件。它的工作原理如下:
取两个字符串x =“Elvis Pr”和y =“Elvis Aaron Presley”
每一项工作都是uni和bi-gram的多重集合:
x = {e, l, v, i, s, _, p, r, el, lv, vi, is, s_, _p, pr}
y = {ex3, lx2, v, i, sx2, _x2, ax2, rx2, o, n, p, y, el, lv, vi, is, s_, _a, aa, ar, ro, on, n_, _p, pr, re, es, sl, le, ey}
现在适用于
中的那些术语{e, l, v, i, s, _, p, r, el, lv, vi, is, s_, _p, pr}
计算产品(f_x(t) / (f_x(t) + f_y(t)))^{f_x(t)/2} * (f_y(t) / (f_x(t) + f_y(t)))^{f_y(t)/2}
所以
e = ((1/15) / (1/15 + 3/37))^(1/30) * ((3/37) / (1/15 + 3/37))^(3/74)
l = ((1/15) / (1/15 + 2/37))^(1/30) * ((2/37) / (1/15 + 2/37))^(2/74)
v = ((1/15) / (1/15 + 1/37))^(1/30) * ((1/37) / (1/15 + 1/37))^(1/74)
i = ((1/15) / (1/15 + 1/37))^(1/30) * ((1/37) / (1/15 + 1/37))^(1/74)
s = ((1/15) / (1/15 + 2/37))^(1/30) * ((2/37) / (1/15 + 2/37))^(2/74)
_ = ((1/15) / (1/15 + 2/37))^(1/30) * ((2/37) / (1/15 + 2/37))^(2/74)
p = ((1/15) / (1/15 + 1/37))^(1/30) * ((1/37) / (1/15 + 1/37))^(1/74)
r = ((1/15) / (1/15 + 2/37))^(1/30) * ((2/37) / (1/15 + 2/37))^(2/74)
el = ((1/15) / (1/15 + 1/37))^(1/30) * ((1/37) / (1/15 + 1/37))^(1/74)
lv = ((1/15) / (1/15 + 1/37))^(1/30) * ((1/37) / (1/15 + 1/37))^(1/74)
vi = ((1/15) / (1/15 + 1/37))^(1/30) * ((1/37) / (1/15 + 1/37))^(1/74)
is = ((1/15) / (1/15 + 1/37))^(1/30) * ((1/37) / (1/15 + 1/37))^(1/74)
s_ = ((1/15) / (1/15 + 1/37))^(1/30) * ((1/37) / (1/15 + 1/37))^(1/74)
_p = ((1/15) / (1/15 + 1/37))^(1/30) * ((1/37) / (1/15 + 1/37))^(1/74)
pr = ((1/15) / (1/15 + 1/37))^(1/30) * ((1/37) / (1/15 + 1/37))^(1/74)
将所有这些相乘并且你应该得到[0.5,1]范围内的数字,这样你就可以通过乘以2并减去1来更有效地将其扩展到[0,1]范围。
但是,这不是离散距离指标,因此您必须使用其他指标索引,例如vp-tree
答案 2 :(得分:1)
Solr提供全功能自动提示功能OOTB。 This link提供了一些从热门查询生成的背景信息。但您可以轻松地对其进行调整以构建一些先验知识,例如您描述的场景。
答案 3 :(得分:1)
看看Cleo,看起来你有一个非常相似的用例。他们使用Bloom过滤器搜索前缀,使用Forward索引删除误报。