MySQL& AJAX预测搜索实施选项

时间:2013-03-05 07:04:06

标签: sql ajax jquery sql-like

我在MySQL数据库的“地址”表中有地址。该表包含一个地址ID列和通常与地址相关的列 - 名称,第1行,第2行,郊区,州,邮政编码等。许多字段允许NULL。

这用于客户端基于Web的界面 - 用户可以通过在文本框中键入任何部分来查找并从表中选择地址。显示匹配项,用户可以选择一个。

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

文本框中的术语被视为以空格分隔的一系列搜索术语,并且每个术语必须出现在任何地址字段中,以便显示以供选择。

Now there are two search terms to match...

我在这几个实现方法之间徘徊:

目前的方法:

  1. 在页面加载时,异步HTTP请求(“AJAX”)用于检索格式良好的列表中的所有地址(所有字段合并为一行,占空白字段)。
  2. 每当文本框收到输入时,jQuery用于查找和显示此列表中的匹配项。
  3. 这种方法的好处是只需要发送一个简单的查询,并且在搜索字段和查看响应之间没有延迟,因为搜索是在客户端完成的(尽管这可能无法很好地扩展 - 见下文)。它还避免了复杂的SQL搜索的需要(我不反对,我只是想实现一些东西作为概念证明,这种方法更快)。

    缺点当然是页面必须在加载页面时检索每个地址,并且数据库可能最终存储数千个地址。

    另一种方法是在用户键入文本框时发送HTTP请求,这将返回与使用SQL搜索表匹配的地址。需要更多请求和更多延迟,但每次只需要检索和传输地址子集。我可以根据需要轻松调整最小术语长度和轮询频率。

    我想知道实现这个SQL方面的最佳方法......

    我最好创建一个视图,它连接所有可搜索的地址列,并使用带有WHERE子句的查询,沿着“concatcolumn LIKE'%term1%'和concatcolumn LIKE'%term2%'和concatcolumn LIKE'% termN%'“?

    非常感谢任何想法或建议。

2 个答案:

答案 0 :(得分: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>';

在客户端,我使用了来自other questions的一些智慧,只是在打字暂停后才进行查询。

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('');
}

我仍然不确定创建视图是否必要/更有效,而不仅仅是在WHERE子句中使用CONCAT_WS的地址表上编写查询...它确实使查询更加简单,但是: p

答案 1 :(得分:0)

绝对不要在搜索之前带回地址,用户不会介意返回结果所需的第二个,使用加载gif来显示你的ajax调用期间发生的事情。

做类似的事情:

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

我也很想使用REPLACE函数删除空格,逗号和句号

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

我也很想在查询结束后使用关键字LIMIT对结果返回的数量进行限制。