给定一个搜索字符串,我需要选择每个记录(在执行搜索的字段中),至少有一个单词以给定文本开头。
例如:
'John Doe'
必须使用以下搜索字符串进行选择:
'joh'
'do'
'JOHN doe'
使用
选择不'ohn'
'oe'
我需要(可能)避免全文搜索。
我发现的工作是
$query = 'SELECT * FROM MYTABLE WHERE SEARCHFIELD LIKE "' . $searchText . '%"'
. 'OR SEARCHFIELD LIKE "% ' . $searchText . '%"'
我在问是否有更好的方法可以做到这一点。
(对于“更好的方式”,我的意思是更好的性能或相同的性能,但更优雅)
此外,由于查询将使用预准备语句构建,我应该如何在搜索字符串中取消 LIKE 元字符?
答案 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毫秒。
记录通常是索引的(没有全文)。
我有几千条记录,查询并不经常运行,所以对我来说是好的 该解决方案可能不适合其他环境。
要使用上述查询构建预准备语句,我使用了此处描述的技术:
结果代码如下:
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 );
/* ... */