Datamapper比较字符串SQL和PHP

时间:2013-04-16 22:13:04

标签: php codeigniter codeigniter-datamapper

我正在尝试使用CodeIgniter和Data Mapper与PHP和MySQL比较两个字符串,我找到了PHP的函数similar_text并在此函数中使用它:

$v = new Vendedor();
$v -> get();
foreach ($v as $vv) {
    $n = $vv -> name . " " . $vv -> lasta_name1 . " " . $vv -> last_name2;
    $vv -> sorteo -> get();
    similar_text($n, $name, $sim);
    if ($sim > 20) {
        $vv -> boleto -> get();
        $ven[$i] = array(
            'id' => $vv -> id, 
            'nombre' => $n, 
            'telefono' => $vv -> phone, 
            'mail' => $vv -> email,  
        );
        $i++;
    }
}

return $ven;

对于Data Mapper,有人等同于similar_text吗? 非常感谢你!

1 个答案:

答案 0 :(得分:0)

在PHP的similar_text()函数中实现的算法在MySQL中不可用。 mysql中有soundex可以与表达式一起使用:

... where name sounds like "some input"

在sql中,所以在你的PHP代码中看起来像这样:

$v = new Vendedor();
$v->where('CONCAT(name, " ", lasta_name1, " ", lasta_name2) sounds like ', $name);
// ...

但是soundex并不适用于非英语文本。您也可以尝试各种levenshtein实现,请参阅thisthis

由于数据库仍然需要比较每一行,所以这两个仍然会有相当糟糕的性能,所以你在这方面并没有真正赢得太多,但是你改变了相似性的算法,这可能并不合适。

如果您决定保留similar_text()函数,则可以使用array_slice()在数组上实现分页,最好只创建一次订单并将信息保存在某个缓存中(memcached,plain files,apc)缓存...)因此可以在不重新计算顺序的情况下提供具有此输入的后续调用,从而更快。我想像这样的东西(缓存部分是选项):

function get_similar_vevendors($name, $offset, $limit) {
    // Imaginary cache library, 
    // it would return the previously cached search results under a key 
    // created from the name
    if (Cache::has('similar_vevendors_'.$name)) {
        $ven = Cache::get('similar_vevendors_'.$name)
    } else {
        // your orignal code here, filling $ven array filled with similar Vendedor's
        // ...
        // saving the created similar vevendors array in cache
        Cache::store('similar_vevendors_'.$name, $ven);
    }

    // return both the count of the results for pagination 
    // and a acting as the current "page" 
    return array(count($ven), array_slice($ven, $offset, $limit));
}

通过这种方式,您可以使用相同的参数通过您在SQL中使用的数组进行分页,并且可以使用以下内容初始化CI的分页库:

// $offset is coming from the links generated by the pager
list($total_rows, $paged_vens) = get_similar_vevendors($name, $offset, $items_per_page);
$this->pagination->initialize(array(
    'per_page'   => $items_per_page,
    'total_rows' => $total_rows,
));