我有很多短语(〜几百万),每个短语少于六七个单词,大多数少于五个,我想看看他们是否“短语匹配”。这是一个搜索引擎营销术语 - 基本上,如果A包含在B中,则短语与B匹配。现在,它们存储在db(postgres)中,我正在执行regexes的连接(请参阅 this question) 。即使在尝试了所有基本的优化技巧(索引等)并尝试提供的建议之后,它的运行速度也不可思议 有更简单的方法吗?我不反对非数据库解决方案。有没有理由认为正则表达式是矫枉过正的,并且比不同的解决方案占用时间更长?
答案 0 :(得分:1)
如果需要了解为什么需要查看哪些短语是其他短语的子集,那就更好了:例如,无论如何,数据库将以这样的方式构建似乎很奇怪:您必须现在就开始工作,因为数据库的格式不合适,所以你应该“修复”数据库或者构建数据库的方式,这是有意义的。
这在很大程度上取决于你对数据做了什么以及为什么,但我发现过去将它分解为单个单词和单词对,然后将资源或短语链接到单个/对。< / p>
例如,为了实现我已经完成的搜索:
来源文字:
Testing phrases to see
条目:
要查看另一个短语是否相似(已授予,未包含在内),您将以相同方式分解另一个短语并计算它们之间常见的短语数。
如果您要使用(例如)“查看阶段到测试”,它仍具有良好的副作用:因为单个单词会匹配..但因为顺序不同,所以对不会,所以它是同时考虑短语(连续的单词),匹配的数量不会那么高,有利于在匹配中用作“得分”。
正如我所说,对我来说,事情对我有用,但听到更多背景/背景会更好,所以我们可以看看能否找到更好的解决方案。
答案 1 :(得分:1)
当您从MaasSQL之前的答案中获得“清理列”时,您可以根据“词组匹配”的工作方式(我不知道),根据包含字符串的长度对此列进行排序。 / p>
然后确保在过程而不是平面查询中以汇聚方式运行比较查询,方法是逐步执行表(使用游标)并通过WHERE语句删除候选对象以及删除已经过的候选对象测试(完全)。您可能需要一个临时表来执行此操作。
我之前的'WHERE'陈述是什么意思?好吧,如果比较值在按长度排序的列中,您将永远不必测试较长的字符串是否与较短的字符串匹配。
删除候选人:从最短的字符串开始,一旦你测试了一定长度的所有字符串,你就可以从比较表中删除它们,因为你要做的任何下一次测试都不会得到匹配
当然,这需要比一个SQL语句更多的编程。并取决于“词组匹配”的工作方式。
DTS或SSIS也可能是您的朋友。
答案 2 :(得分:1)
进行子字符串匹配的理想算法是AhoCorsick。
虽然您必须从数据库中读取数据才能使用它,但与更天真的方法相比,它的速度非常快。
有关子字符串匹配的相关问题,请参阅here:
和here用于Java中的AhoCorsick实现: