如何针对大型规则集(5000+并且不断增长)构建高效的电子邮件过滤器

时间:2012-04-18 17:21:35

标签: python regex email postgresql

我正在构建一个电子邮件过滤器,我需要一种方法来有效地将单个电子邮件与大量过滤器/规则匹配。电子邮件可以在以下任何字段中匹配:

  • 来自姓名
  • 来自地址
  • 发件人姓名
  • 发件人地址
  • 主题
  • 讯息正文

目前有超过5000个过滤器(并且还在增长),它们都在我们的PostgreSQL(9.1)数据库的单个表中定义。每个过滤器可能包含一个或多个上面填充了Python正则表达式的字段。

目前正在进行过滤的方法是选择所有过滤器并将其加载到内存中。然后,我们针对每封电子邮件迭代它们,直到在所有非空白字段上找到肯定匹配。不幸的是,这意味着任何一封电子邮件都可能有多达30,000(5000 x 6)次重新匹配操作。显然,这不会随着更多过滤器的添加而扩展(实际上它已经没有)。

有更好的方法吗?

到目前为止我考虑的选项:

  1. 将保存的python正则表达式转换为POSIX样式表达式,以利用PostgreSQL的SIMILAR TO表达式。这真的会更快吗?在我看来,它只是将负载转移到其他地方。

  2. 基于每个用户定义过滤器。虽然这不太实际,因为我们的系统用户实际上可以从大量预定义过滤器中受益。

  3. 切换到基于文档的搜索引擎,如弹性搜索,其中第一封要过滤的电子邮件将保存为规范表示。通过查找类似的电子邮件,我们可以缩小到要测试的特定功能集并获得正面匹配。

  4. 切换到贝叶斯过滤器,它还可以为我们提供一些机器学习功能,以检测类似的电子邮件或对现有电子邮件的更改,这些电子邮件仍然可以匹配的概率足以猜测它们是相同的。这听起来很酷,但我不确定它的扩展性也会特别好。

  5. 还有其他选择或方法需要考虑吗?

2 个答案:

答案 0 :(得分:3)

PostgreSQL版本9.1中的trigram支持可能会为您提供所需的内容。

http://www.postgresql.org/docs/9.1/interactive/pgtrgm.html

几乎可以肯定,它将成为9.2(计划于2012年夏季发布)的可行解决方案,因为新版本知道如何使用trigram索引快速匹配正则表达式。在我们的商店,我们发现三元组指数的速度非常好。

另外,如果您想要进行“最近邻居”搜索,根据与搜索参数的相似性找到K个最佳匹配,则三元组索引非常棒 - 它实际上会从索引扫描中按顺序返回行“距离”。搜索KNN-GiST进行撰写。

答案 1 :(得分:0)

这些正则表达式有多复杂?如果它们确实是正则表达式(没有所有疯狂的python扩展),那么你可以将它们全部组合成一个正则表达式(作为备选方案),然后使用一个简单的(即内存中)正则表达式匹配器。

我不确定这会起作用,但我怀疑你会惊喜地发现正则表达式编译成一个小得多的状态机,因为它会合并常见状态。

另外,对于快速正则表达式引擎,请考虑使用快速扫描的nrgrep。从一个标题跳到另一个标题时,这应该会给你加速(我自己没有使用它,但它们是朋友的朋友,当我阅读它时,纸张看起来非常整洁)。