Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/249.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在一些不完整的数据中查找单个用户记录?_Php_Mysql_Algorithm_Levenshtein Distance - Fatal编程技术网

Php 在一些不完整的数据中查找单个用户记录?

Php 在一些不完整的数据中查找单个用户记录?,php,mysql,algorithm,levenshtein-distance,Php,Mysql,Algorithm,Levenshtein Distance,我正在建立一个用户必须注册的系统。这些用户也可能是更大客户数据库的一部分,我想将注册与更大客户数据库中的用户ID联系起来 客户数据库有些不完整。有些客户只有一个电话号码,根据输入者/输入者的不同,它可能在不同的地方有空间。其他客户只有一个电子邮件地址,而且很可能有打字错误,因为它是手写的,然后在以后由其他人处理。真是噩梦 我想找到与用户在我正在构建的系统上输入的内容最接近的记录。这些数据非常直接,将得到验证。这些数据: 名字 姓 DOB(YYYY-MM-DD) 电子邮件地址 电话号码 我最初

我正在建立一个用户必须注册的系统。这些用户也可能是更大客户数据库的一部分,我想将注册与更大客户数据库中的用户ID联系起来

客户数据库有些不完整。有些客户只有一个电话号码,根据输入者/输入者的不同,它可能在不同的地方有空间。其他客户只有一个电子邮件地址,而且很可能有打字错误,因为它是手写的,然后在以后由其他人处理。真是噩梦

我想找到与用户在我正在构建的系统上输入的内容最接近的记录。这些数据非常直接,将得到验证。这些数据:

  • 名字
  • DOB(YYYY-MM-DD)
  • 电子邮件地址
  • 电话号码
我最初的想法是使用Levenshtein距离算法来计算每个字段的“字符串距离”,除非它们是空的,然后按总分排序。下面的代码中没有显示以保持内容的美观和可读性,但我显然也会修剪(甚至可能只是删除)所有空白

作为伪代码:

SELECT c.customerID
FROM   customers c
WHERE  ( c.first_name IS NULL OR ( Levenshtein(c.first_name, $first_name) < 3 ) )
AND    ( c.last_name IS NULL OR ( Levenshtein(c.last_name, $last_name) < 3 ) )
AND    ( c.email IS NULL OR ( Levenshtein(c.email, $email) < 3 ) )
AND    ( c.telephone IS NULL OR ( Levenshtein(c.telephone, $telephone) < 3 ) )
选择c.customerID
来自客户c
其中(c.first_name为NULL或(Levenshtein(c.first_name,$first_name)<3))
和(c.last_name为空或(Levenshtein(c.last_name,$last_name)<3))
和(c.email为空或(Levenshtein(c.email,$email)<3))
和(c.telephone为空或(Levenshtein(c.telephone,$telephone)<3))
仅供参考,我正在对这两个数据库使用PHP(Laravel)和MySQL


我在这条路上走对了吗?或者我应该使用莱文施坦以外的东西吗?我是否应该比较所有领域分数的某种组合?

这首歌肯定是对的,但我要补充几点

准备数据

首先,为了匹配,我建议对数据进行转换以消除可能存在的所有噪音,例如将字符串转换为大写,删除空白,删除电话号码中的所有非数字,等等

在不完整数据中查找最接近的匹配项

其次,设置任意阈值(如上面的“小于3”)会使它有点僵硬。虽然CPU要求更高,但您最好按“差异系数”对结果进行排序:

显然,当差异高得离谱时,您可以添加一些不匹配的安全性,但您明白了。如果两个对象在同一字段中都缺少数据(例如,两个对象都缺少电子邮件),该方法仍然可以。当只有一方缺阵时,问题就出现了——然后我们会因为差距而受到很大的打击。我们可能会将查询进一步复杂化以避免它:

ORDER BY
(if(c.first_name is null OR c.first_name = '' OR $first_name = '', 0, Levenshtein(c.first_name, $first_name))) +
...
为简洁起见,缩短为一行-只有在有数据可比较的情况下,我们才计算Lev距离

缺点


对于所有与大于X的差异因子匹配的记录,你可能会想到某种标志,让人类来决定。经过一段时间的复习,我相信你会想出更多的规则来实现自动化。

酷。这是有道理的。我会尽可能像你提到的那样准备好数据。我对上述问题的担忧是,数据库中可能根本没有现有客户。甚至可能有没有这些数据的行(例如,我们可能只有一个地址,我不收集),所以比较NULL和NULL会得到一个完美的匹配。是的,但我认为这是有意义的-如果两边的特定属性中都没有数据,这就不会影响因子。没有任何数据(在任何领域)会是一个问题,但这是验证。让我更新一下答案。
ORDER BY
(if(c.first_name is null OR c.first_name = '' OR $first_name = '', 0, Levenshtein(c.first_name, $first_name))) +
...