使用AJAX和PHP创建多字段实时搜索引擎时遇到问题。
到目前为止,没有必要搜索多个字段,所以我有一个简单的查询,只适用于一个字段。
由于使用onkeyup
功能进行实时搜索,我发现了一些问题。我需要解释的第一个问题是:
表的结构非常简单:zipcode | city
例如,有人输入12345
;当然这将是邮政编码。但是如果有人输入12345 hometown
所以第一个关键字是邮政编码,第二个城市是第二个?
关键字将使用preg_split('/[\s]+/', $search_term)
进行拆分,因此我会收到一个包含将要搜索的单个关键字的数组。在上面的情况中,它将是:key[0] => 12345
和key[1] => hometown
。
我使用的查询是:
$where = "";
$search_term = preg_split('/[\s]+/', $search_term); //splits the whole string into single keywords
$total_search_terms = count($search_term); //counts the array-keys from $search_term
foreach ($search_term as $key=>$single_term) {
$where .= "`zipcode` LIKE '$single_term%' OR `city` LIKE '$single_term%' ";
if ($key != ($total_search_terms - 1)){ //adds AND to the query in case in case of a non empty array-key
$where .= " AND ";
}
}
$query = $db->query("SELECT COUNT(*) FROM table WHERE $where");
...
好的,到目前为止一切顺利。现在问题是关键字可以反复匹配每个字段。
举一个例子:
如果从上面输入12345 hometown
,则表示key[0] => 12345
可以匹配字段zipcode
或city
。此条件仅适用于key[1] => hometown
,即使这可以匹配字段zipcode
或city
。因此,即使进入其他方向:hometown 12345
也意味着相同。
这是我遇到的第一个问题。
我正在寻找构建查询的逻辑。因此,如果输入12345 hometown
,我希望有类似的内容:
当key[0] => 12345
与字段zipcode
匹配时,如果key[1] => hometown
或zipcode
匹配city
,则key[0]
匹配zipcode
因此,key[1]
需要city
才符合逻辑。
更新
好的,告诉我的第二个问题,我希望你看看david strachan
的答案
他提到当城市包含多个字符串时会引起问题。假设搜索字符串类似于:
12345 New York
关键是:
key[0] => 12345, key[1] => New, key[2] => York
好的,现在问题是我可以检查其中一个键是否包含整数,如果字符串长度恰好为5,我知道它将是zipcode。
key[0] => 12345 //if ( stringlen(key[0|) === 5) === true && is_int(key[0]) === true) {zipcode}
到目前为止这么好,但真正的问题是城市串背后的逻辑。我的第一个想法是,我可以说所有不包含整数的键必须是城市,所以我可以将它们转换成一个键。
key[1] => New, key[2] => York //if ( !is_int(key[1|) === true && !is_int(key[2|) === true) {$create_one_key = array_fill_keys(key[1], key[1]+key[2]);}
好吧,但是以后我想在将来添加街道名称呢?我不知道如何分离和测试街道名称甚至城市名称。
答案 0 :(得分:1)
另一种方法是使用JQuery Autocomplete来搜索MySQL数据库。以下代码使用PDO。
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.2/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script type="text/javascript">
jQuery(document).ready(function(){
$('#zipsearch').autocomplete({source:'suggest.php', minLength:2});
});
</script>
<style type="text/css">
li.ui-menu-item { font-size:10px}
</style>
</head>
<body>
<h2>jQuery UI Autocomplete - With MySQL </h2>
<form onsubmit="return false;">
Search:
<input id="zipsearch" type="text" size ="60"/>
</form>
<强> suggest.php 强>
require("dbinfo.php");//db connection strings
// if the 'term' variable is not sent with the request, exit
if ( !isset($_REQUEST['term']) )
exit;
$term = $_REQUEST['term'];
if (is_numeric($term)){
$query = "SELECT * from ziptest WHERE zip LIKE ? OR address LIKE ? LIMIT 0,10";
}else{
$query = "SELECT * from ziptest WHERE city LIKE ? OR state LIKE ? LIMIT 0,10";
}
$term.="%";
// connect to the database
try {
$dbh = new PDO("mysql:host=$host;dbname=$database", $username, $password);
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
// Prepare statement
$stmt = $dbh->prepare($query);
// Assign parameters
$stmt->bindParam(1,$term);
$stmt->bindParam(2,$term);
// setting the fetch mode
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$stmt->execute();
$data = array();
while($row = $stmt->fetch()) {
$data[] = array(
'label' => $row['address'] .', '. $row['city'] .', '. $row['state'] .', '.$row['zip'] ,
'value' => "ID ".$row['id'] .': '.$row['address'] .', '. $row['city'] .', '. $row['state'] .', '.$row['zip']
);
}
echo json_encode($data);
}
catch(PDOException $e) {
echo "I'm sorry I'm afraid you can't do that.". $e->getMessage() ;// Remove or modify after testing
file_put_contents('PDOErrors.txt',date('[Y-m-d H:i:s]'). $e->getMessage()."\r\n", FILE_APPEND);
}
// close the connection
$dbh = null;
答案 1 :(得分:0)
通过添加0检查$search_term[0]
是字符串(城市)还是int(zipcode)然后相应地格式化查询。
$search_term = '1234 paisley';
$search_term = preg_split('/[\s]+/', $search_term); //splits the whole string into single keywords
$total_search_terms = count($search_term); //counts the array-keys from $search_term
$test = $search_term[0]+0;//If string returns 0
if($total_search_terms == 1){
if ($test == 0 ){
$where = "WHERE `city` LIKE `%$search_term[0]%`";
}else{
$where = "WHERE `zipcode` LIKE `%$search_term[0]%` ";
}
}else{
if ($test == 0 ){
$where = "WHERE `zipcode` LIKE `%$search_term[1]%` AND `city` LIKE `%$search_term[0]%`";
}else{
$where = "WHERE `zipcode` LIKE `%$search_term[0]%` AND `city` LIKE `%$search_term[1]%`";
}
}
$query = "SELECT COUNT(*) FROM table $where";
echo $query;
一个问题是你如何对待纽约。我会告诉你如何解决这个问题。
编辑
纽约$total_search_terms > 2