我正在尝试基本上进行反向完整测试搜索,但不知道最好的方法去做。
基本上我有一张如下所示的关键短语表:
id - 短语
1 - “你好世界”
2 - “再见世界”
3 - “这是我的世界”
然后我有一个设置字符串,例如“欢迎来到hello world组”。我想找到我的表中与短语完全匹配的所有行的ID。含义“o the”不匹配,因为单词是“to the”。 “ello”也不匹配,因为世界是“你好”。
使用全文搜索,可以通过搜索以下内容轻松实现:
反对('“你好世界”'在布尔模式中);
问题是,我不相信我可以使用全文搜索,因为全文搜索会找到包含单个短语的所有行。我想要所有与一组相匹配的短语(来自一组已知的短语)。
我知道如何使用以下方法使用RegEx执行此操作,但这是缓慢的方法。在一张有400,000个关键短语的桌子上花了40多秒:
在哪里“我知道我想搜索的数据在这里”REGEXP CONCAT('[[:<:]]',phrases
,'[[:>:]]')
我需要的是一种更优化的方法。我怎么可能将其作为全文搜索来进行,即使我必须暂时将其添加到表中而不实际单独检查每个关键字的LOOP。
我非常感谢您的反馈,因为这确实导致我的网站在添加新数据时滞后。
答案 0 :(得分:2)
如果您愿意考虑从数据库中读取短语并构建用于优化短语检测的单独数据结构的解决方案,则可以使用两种主要技术来解决问题。哪一个最适合您取决于许多因素,特别是:
选项1:短语的哈希表这意味着您只需将每个短语作为键插入哈希表(又名词典或哈希映射) 在许多编程语言中)。短语id成为值。更新既快速又简单,但检测给定字符串中的短语可能很难:首先,您需要对字符串进行标记,并确保短语仅出现在标记边界之间。其次,您需要在散列中查找不仅针对每个令牌,还针对连续令牌的每对,三倍,四倍等。如果目标字符串通常很短,这仍然有效。您还可以在磁盘上维护哈希表的副本,例如使用Berkeley DB。大多数编程语言的标准库中都有现成的模块。
选项2:搜索trie (或稍微更高级,最小化搜索线索或有限状态机)。这可以以非常节省空间的方式实现,但通常大于哈希表(尽管400k条目 根本不是问题)。短语检测期间的一大优势是,您无需在进行查找之前剪切令牌(或令牌边界之间的候选短语)。而是在文本中的每个候选起始位置执行最长匹配查找。尽管在大多数编程语言中都没有用于此的标准库模块,但是可以存储在磁盘上。在trie中更新非常容易,但在最小化的trie或FST中可能会变得困难(并且可能非常耗时)。
两个选项允许在磁盘上维护数据结构(或者将其副本存储在磁盘上,而实际的查找发生在内存中)。但是你不会得到交易安全或容错(我知道你不是在寻找)。
答案 1 :(得分:0)
您可以使用搜索引擎。例如solr。您可以针对文本设置特定搜索过滤器。 +仅搜索单词。 +它的速度非常快。
或者,第二个想法是你可以创建自己的表来存储短语的所有单词和id。并搜索该表仅加工单词。它会更快,因为你可以在单词上添加索引,然后完全添加短语。