mysql喜欢在字符串上匹配完整的单词或单词的开头

时间:2013-10-31 22:31:51

标签: mysql sql-like

给定一个搜索字符串,我需要选择每个记录(在执行搜索的字段中),至少有一个单词以给定文本开头。

例如:

'John Doe'

必须使用以下搜索字符串进行选择:

'joh'
'do'
'JOHN doe'

使用

选择
'ohn'
'oe'

我需要(可能)避免全文搜索。

我发现的工作是

$query = 'SELECT * FROM MYTABLE WHERE SEARCHFIELD LIKE "' . $searchText . '%"'
                                . 'OR SEARCHFIELD LIKE "% ' . $searchText . '%"'

我在问是否有更好的方法可以做到这一点。

(对于“更好的方式”,我的意思是更好的性能相同的性能,但更优雅

此外,由于查询将使用预准备语句构建,我应该如何在搜索字符串中取消 LIKE 元字符?

2 个答案:

答案 0 :(得分:1)

使用此:

$query = "SELECT * FROM MyTable WHERE searchfield LIKE CONCAT('%', ?, '%')";

您不需要OR条件 - 如果字段与search%匹配,则它也会匹配%search%

答案 1 :(得分:1)

正如问题中已经说明的那样查询

$query = 'SELECT * FROM MYTABLE WHERE SEARCHFIELD LIKE "' . $searchText . '%"'
                                . 'OR SEARCHFIELD LIKE "% ' . $searchText . '%"'

适用于匹配SEARCHFIELD包含以(或等于)$searchText开头的单词的记录


关于性能,我已经在我的开发机器MBP 2,2 GHz i7 quad core上进行了测试:

在4.000条记录上搜索单词大约需要40毫秒。

记录通常是索引的(没有全文)。

我有几千条记录,查询并不经常运行,所以对我来说是好的 该解决方案可能不适合其他环境。


要使用上述查询构建预准备语句,我使用了此处描述的技术:

Escaping MySQL wild cards

结果代码如下:

function like($s, $e)
{
    return str_replace(array($e, '_', '%'), array($e . $e, $e . '_', $e . '%'), $s);
}

/* ... */

/* create a prepared statement */
$stmt = $mysqli->prepare(
    'SELECT * FROM MYTABLE WHERE SEARCHFIELD LIKE ? ESCAPE "=" OR SEARCHFIELD LIKE ? ESCAPE "="'
); 

if( $stmt )
{
    /* escape the text */
    $escSearchText = like( $searchText, "=" );

    /* 'like' parameters */
    $like1 = $escSearchText . "%";
    $like2 = "%" . $escSearchText . "%";

    /* bind parameters for markers */
    $stmt->bind_param( "ss", $like1, $like2 );

/* ... */