2013-10-31 62 views
4

給定一個搜索字符串,我需要選擇每個記錄(在該字段中執行搜索),至少有一個單詞以給定的文本開頭。mysql喜歡匹配完整的單詞或字符串的開始

例如:

'John Doe' 

必須與像搜索字符串進行選擇:

'joh' 
'do' 
'JOHN doe' 

'ohn' 
'oe' 

選擇我需要的(可能)以避免全文搜索。

我已經找到工作是

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

我問是否有更好的方法來做到這一點。

(對於「更好的方式」我的意思是更好的性能相同的性能,但更優雅

而且,因爲查詢將建成了一份聲明,我應該怎麼反轉義LIKE搜索字符串中的元字符?

回答

1

正如已經在質詢時所查詢

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

作品匹配的記錄,其中SEARCHFIELD包含開頭一個字(或等於)$searchText


關於業績我我在我的開發機器上進行了測試MBP 2,2 GHz i7 quad core

在4.000個記錄上搜索單詞需要aro和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); 

/* ... */ 
1

使用此:

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

你不需要OR條件 - 如果一個字段匹配search%,它也將匹配%search%

+0

否,將匹配'oe'或'ohn'。我會編輯我的問題以便明確表示 – Paolo

+0

'LIKE'不能進行單詞匹配,它只是匹配字符串。 – Barmar

+0

您需要使用'RLIKE'而不是'LIKE'並創建一個正則表達式。相同的基本方法仍然有效,您只需使用匹配單詞開頭而不是第一個'%'的正則表達式。 – Barmar

相關問題