2013-03-05 29 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