【发布时间】:2012-08-02 17:38:09
【问题描述】:
我有一大堆短字符串。有哪些算法和索引策略可以过滤包含子字符串的项目列表?例如,假设我有一个列表:
val words = List(
"pick",
"prepick",
"picks",
"picking",
"kingly"
...
)
如何找到包含子字符串“king”的字符串?我可以像这样暴力破解这个问题:
words.filter(_.indexOf("king") != -1) // yields List("picking", "kingly")
这仅适用于小型套装;今天我需要支持 1000 万个字符串,未来的目标是数十亿。显然我需要建立一个索引。 什么样的索引?
我已经研究过使用存储在 MySQL 中的 ngram 索引,但我不确定这是否是最好的方法。当搜索字符串长于 ngram 大小时,我不确定如何优化查询索引。
我也考虑过使用Lucene,但是这个是围绕token匹配优化的,不是子串匹配,而且似乎不支持简单子串匹配的需求。 Lucene 确实有一些与 ngram 相关的类(org.apache.lucene.analysis.ngram.NGramTokenFilter 就是一个例子),但这些似乎是用于拼写检查和自动完成用例,而不是子字符串匹配,而且文档很薄。
我应该考虑哪些其他算法和索引策略?有没有支持这个的开源库?能否使 SQL 或 Lucene 策略(如上)起作用?
说明需求的另一种方式是使用 SQL:
SELECT word FROM words WHERE word LIKE CONCAT('%', ?, '%');
其中? 是用户提供的搜索字符串,结果是包含搜索字符串的单词列表。
【问题讨论】:
-
后缀树应该可以完成这项工作。
-
这 1000 万个字符串是否不同?
-
@nhahtdh 你能提供更多细节吗?每个字符串 1 个后缀树?那不是需要对所有 1000 万棵树进行一次查询吗?
-
@landon9720:所有字符串都有 1 个后缀树。
标签: database algorithm data-structures lucene