2

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

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

该机场因澳大利亚的“str”而被列出

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

现在有两个搜索词要匹配...

为此,我在几种实现方法之间纠结:

目前的方法:

  1. 在页面加载时,异步 HTTP 请求(“AJAX”)用于检索格式良好的列表中的所有地址(所有字段组合成一行,占空白字段)。
  2. 每当文本框接收到输入时,jQuery 用于在此列表中查找和显示匹配项。

这种方法的好处是只需要发送一个简单的查询,并且在输入搜索字段和查看响应之间没有延迟,因为搜索是在客户端完成的(尽管这可能无法很好地扩展 - 见下文) . 它还避免了对复杂 SQL 搜索的需要(我并不反对,我只是想实现一些东西作为概念证明,而且这种方法更快)。

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

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

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

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

任何想法或建议将不胜感激。

4

2 回答 2

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>';

在客户端,我从其他 问题中汲取了一些智慧,使其仅在输入暂停后才进行查询。

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

于 2013-03-06T02:13:24.263 回答
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返回的结果数量。

于 2013-03-05T07:21:21.153 回答