从MySQL结果中删除类似结果的快速方法

时间:2013-06-20 19:52:35

标签: php mysql duplicates duplicate-removal

我运行的网站存在由其用户发布重复内容的问题。因此,当访问者搜索内容时,它会返回看起来完全相同的结果。

问题是重复的内容不是抄送。可能会在这里和那里更改一个词,或者它会在几天后发布,但不需要额外的结果,因为它们基本上是重新发布的。

一个例子是:

  

标题:出售裤子描述:我卖的是一条裤子。   他们有洞。联系Rob于1234

     

标题:出售裤子描述:我卖的是一条裤子。   他们有一些漏洞。联系Rob

     

标题:我的裤子出售说明:我卖的是一双   长裤。他们有洞。联系Rob于1234

是否有某种形式的算法(最好是内置于PHP和快速),可以准确地捕获这些重复项?它将搜索大约50个项目的结果集,每个项目最多包含500个字符的文本。

编辑:我还应该补充说,类似的结果可能不会彼此相邻,所以我不能简单地将当前结果与前一个结果进行比较。在理想的世界中,它将类似于SELECT title,desc FROM database WHERE id IN(10,40,54,143,444)AND UNIQUE(title,desc)> 90%。

3 个答案:

答案 0 :(得分:1)

忘记上面的回复并使用以下代码:

    class similarText
    {
        private $arrayResults = array();
        private $text;

        public function test( $text, $accepted_percentage = 70 )
        {
            if( count( $this->arrayResults ) )
            {
              foreach( $this->arrayResults as $result )
              {
                similar_text( $result, $text, $percent );

                if( ( (int) $percent ) >= $accepted_percentage )
                {
                  $this->save( $text );
                  return (int) $percent;
                }
              }
            }
            $this->save( $text );
            return 0;
        }

        private function save( $text )
        {
            $this->arrayResults[ $text ] = $text;
        }
    }


    $similar = new similarText();

    while( /*[ $fetch = ... ]*/ )
    {
        $title = $fetch['title'];
        $description = $fetch['description'];

        if( $similar->test( $title, 70 ) || $similar->test( $description, 70 ) )
        {
          continue;
        }
    }

答案 1 :(得分:0)

我建议使用此

Levenshtein

它计算需要多少次插入删除和替换才能使字符串相等。

您需要在数据库结果之后执行此操作。

然后你选择一个像50这样的任意数字来比较每个字符串之间的距离。现在,由于只使用2个字符串,你需要运行一个循环来比较每个字符串,我不确定你有多少结果(没有数据)所以很难说它运行效率有多高。< / p>

levenshtein在O(m * n)中运行,这是字符串的长度,如果你将它与每个字符串进行比较,它可能会很昂贵,但很难让它更快。

如果您能提供更完整的结果样本,那将会有所帮助。如同所有结果类似的帖子,如你所示或其他结果混合在一起。

也许你可以拆分sql语句来获得类似的结果并运行levenshtein?

答案 2 :(得分:0)

让我理解你,你不想显示类似的结果吗?

您可以使用 similar_text

例:

$ArrayResults = array();
$found = 0;
$accepted_percentage = 70;

while( /*[ $fetch = ... ]*/ )
{
    $title = $fetch['title'];
    if( count( $ArrayResults ) )
    {
      foreach( array_unique( $ArrayResults ) as $result )
      {
        similar_text( $result, $title, $percent );
        if( $percent >= $accepted_percentage )
        {
          $found = 1;
        }
      }
    }
    if( $found )
    {   
      $found = 0;
      continue;
    }
    $ArrayResults[ $title ] = $title;
}