Ruby on rails 搜索电子邮件地址数组以查找任意两个地址之间的相似性

Ruby on rails 搜索电子邮件地址数组以查找任意两个地址之间的相似性,ruby-on-rails,algorithm,mongodb,mongoid,Ruby On Rails,Algorithm,Mongodb,Mongoid,我正在寻找一种方法,通过数据库搜索,找到电子邮件地址之间的相似之处。我能找到的唯一解决方案是O(N^2),它涉及一个嵌套循环。基本上是抓取一个电子邮件地址,然后一遍又一遍地对照其他地址进行检查。这将是非常消耗,因为我在一个数据库中处理100000个电子邮件地址。如果有区别,这将作为RubyonRails应用程序的后台作业实现 有没有办法做到这一点 我只是在寻找基本的相似之处。例如 docjohnson@gmail.com docjohnson1@gmail.com docjohnson333@g

我正在寻找一种方法,通过数据库搜索,找到电子邮件地址之间的相似之处。我能找到的唯一解决方案是O(N^2),它涉及一个嵌套循环。基本上是抓取一个电子邮件地址,然后一遍又一遍地对照其他地址进行检查。这将是非常消耗,因为我在一个数据库中处理100000个电子邮件地址。如果有区别,这将作为RubyonRails应用程序的后台作业实现

有没有办法做到这一点

我只是在寻找基本的相似之处。例如

docjohnson@gmail.com
docjohnson1@gmail.com
docjohnson333@gmail.com
docjohnson@hotmail.com
我希望所有这些标记彼此相似

谢谢你的帮助


编辑:我正在使用一个通过Mongoid连接到ROR的Mongo数据库,如果这改变了游戏的话。

为每个电子邮件地址计算一个“签名”;例如,签名可能是地址用户名部分的前五个字符。对所有电子邮件地址进行排序,将具有相同签名的电子邮件地址放在一起;如果您的签名算法做得很好,那么每组签名都应该指向同一个人。您必须根据数据和相似性定义调整签名算法。

我建议您从“规范化”电子邮件开始:

  • 从用户名部分去除尾随数字,例如,
    john123
    ->
    john

  • 可能从用户名中删除一些标点符号,例如,
    john.smith
    ->
    johnsmith

  • 从域部分删除一些主机,例如,
    mail.foo.com
    ->
    foo.com
    ;但不是
    math.mit.edu
    ->
    mit.edu


  • 完成1和2之后,您应该将原始电子邮件收集到一个哈希表中,该哈希表将规范用户名映射到原始用户名,这样完成后,您只需迭代规范用户名。

    我建议添加一些有关您正在使用的数据库类型的信息,并适当标记您的问题。如果可以通过查询来处理,它可能会向其他专家开放。您是否尝试过类似于查询的方法?“基本相似性”是模糊的,但这可能是你想要的,全文或Lucene搜索可能是你最好的选择。我刚刚在我的问题中添加了数据库信息,谢谢你的建议!我没试过那样的东西。我有点困惑这将如何显著更快,好像我理解正确,我仍然需要嵌套循环来检查所有内容。你知道“相似”的确切含义吗?可能第一种方法是在使用算法之前先提出一个相似性度量。全文索引或Lucene索引将允许您执行搜索,并为每个结果获得一定的“相关性”分数。你可以为被认为是“相似的”设置一个阈值。这可能是多余的,但是那些搜索通常会更快,并且不再需要O(n ^ 2)循环。这绝对是一个需要考虑的想法,尽管我觉得优化签名算法可能很困难。比嵌套循环更好的想法是选择一个简单的签名算法,运行它,看看你得到了什么,根据经验修改它,重复几次迭代,然后在“足够接近”时退出;你在尝试接近,而不是完美。你可以用你的签名功能做很多事情;例如,您可能会将gmail.com、yahoo.com或hotmail.com的所有实例更改为gmailyahootmail,然后添加用户名的前八个字符,为您提供的所有示例提供gmailyahootmaildocjohns签名。我开始越来越喜欢这个想法。一个好的签名算法的要素是对数据的丰富知识、构建算法细节的想象力以及对许多类似算法结果的重复测量。例如,您是否可以使用七个、八个或九个字符的用户名获得更好的集群?你的任务是否成功将取决于你对“足够接近”的定义。我的建议是保持简单,尽早宣布成功,并随着时间的推移慢慢增加复杂性,因为经验表明这是必要的。