2013-03-05 31 views
2

我在MySQL數據庫的「地址」表中有地址。該表包含一個地址ID列和通常分類的地址相關列 - 名稱,行1,行2,郊區,州,郵政編碼等。許多字段允許NULL。MySQL和AJAX預測搜索實現選項

這用於客戶端的基於Web的界面 - 用戶可以通過在文本框中鍵入任意部分,從表中找到並選擇一個地址。匹配顯示,用戶可以選擇一個。

The Airport is listed because of the 'str' in Australia

在文本框中的條款被視爲一個空格分隔的一系列搜索詞,而有關條款的每一個都必須出現在任何地址字段爲它顯示出來以供選擇。

Now there are two search terms to match...

我幾個實施方法之間撕開此:

當前方法:

  1. 在頁負載,異步HTTP請求( 「AJAX」)被用來檢索格式良好的列表中的所有地址(所有字段組合成一行,佔空白字段)。
  2. 只要文本框接收到輸入,就會使用jQuery查找並顯示此列表中的匹配項。

這種方法的好處是隻需要發送一個簡單的查詢,並且在搜索字段中輸入內容和查看響應之間沒有任何延遲,因爲搜索是在客戶端完成的(儘管這可能不會規模好 - 見下文)。它也避免了對複雜的SQL搜索的需求(我並不反對,我只是想實現一些東西來作爲概念證明,而且這種方法更快)。

不利的一面是,當頁面加載時,頁面必須檢索每個地址,並且數據庫可能最終會存儲數千個地址。

另一種方法是在用戶鍵入文本框時發送HTTP請求,該文本框將返回與使用SQL搜索表匹配的地址。需要更多的請求和更多的延遲,但每次只需要檢索和傳輸一部分地址。我可以根據需要輕鬆調整最短期限和輪詢頻率。

我想了解一下實現這個SQL方面的最佳途徑......

我建議最好是去創建它串接所有的搜索地址欄視圖和查詢中使用沿着WHERE子句「concatcolumn LIKE'%term1%'和concatcolumn LIKE'%term2%'和concatcolumn LIKE'%termN%'」的行?

任何想法或建議將不勝感激。

回答

2

我已經找到了一個我很滿意的解決方案。

首先創建包含所述可搜索的地址字段級聯的圖:

CREATE VIEW address_concat AS 
SELECT address_id, CONCAT_WS(' ', address_name, address_line_1, address_line_2, suburb, postcode, state, country) AS full_address 
FROM address 

當接收到與搜索串的請求時,我解析它在PHP和使用該視圖以查找匹配(以下代碼被清潔並去除不相關的東西 - 數據消毒等):

$terms = explode(' ', preg_replace('/\s+/', ' ', $_GET['find_address'])); //get array of terms 
$where = " WHERE full_address LIKE '%".implode("%' AND full_address LIKE '%", $terms)."%' "; //turn array into WHERE clause 

//query database to find matches 
$result = $db->query("SELECT a.* FROM address a JOIN address_concat ac ON a.address_id = ac.address_id ".$where." ORDER BY IFNULL(IF(address_name = '', NULL, address_name), address_line_1)"); 

if ($result->num_rows > 0) 
{  
    //construct output 
    $output = '<ul>'; 

    while ($row = $result->fetch_assoc()) 
     $output .= '<li val_id="'.$row['address_id'].'">'.make_address(...).'</li>'; 

    $output .= '</ul>'; 
} 
else 
    $output = '<p>No matches found.</p>'; 

在客戶端,我使用了一些智慧otherquestions,使其只在打字暫停後查詢。

var typingTimer; 

$('input#filterbox').bind('input', function() 
{ 
    var textfield = $(this); 

    //code to hide/show "clear text field" box eliminated, etc 

    clearTimeout(typingTimer); 
    typingTimer = setTimeout(function() {doFilterUpdate(textfield);}, 750); 

}); 

function doFilterUpdate (target) 
{ 
    if (target.val().length >= 3) 
     $('div#resultlist').load('inc/ajax.php?find_address=' + encodeURIComponent(target.val())); 
    else 
     $('div#resultlist').html(''); 
} 

我還不能肯定,如果在創建視圖是必要的/不是僅僅寫在使用CONCAT_WS的WHERE子句中的地址表的查詢更加有效......它確實使查詢變得簡單許多,雖然:P

0

絕對不要在搜索之前帶回地址,用戶不會介意第二次返回結果,使用加載gif來顯示在您的ajax調用過程中發生的事情。

做這樣的事情:

SELECT columns 
FROM table 
WHERE  searchterm LIKE '%' + column1 + '%' 
     OR searchterm LIKE '%' + column2 + '%' 
     OR searchterm LIKE '%' + column3 + '%' 

我也非常想使用的REPLACE函數刪除空格,逗號和fullstops

REPLACE(REPLACE(REPLACE(searchterm,' ',''),',',''),'.','') LIKE '%' + column1 + '%' 

我也被引誘放在一個極限在查詢結束後使用關鍵字LIMIT返回的結果數。

+0

像這樣的搜索(儘管假設你混淆了術語/列佔位符)需要考慮多個搜索術語並在每個領域搜索它們......例如「(col1 LIKE term1 OR col2 LIKE term1)AND(col1 LIKE term2 OR col2 LIKE term2)」...因此,爲什麼我想知道是否所有可搜索列連接成一個視圖值得... – Greg 2013-03-05 07:38:48

+0

在這種情況下您需要將搜索詞分割爲空格,然後執行column1 LIKE'%'+ searchterm1 +'%'等 – twoleggedhorse 2013-03-05 08:34:57