0

AJAX と PHP を使用して複数フィールドのライブ検索エンジンを作成する際に問題があります。

これまでは、複数のフィールドを検索する必要はなかったので、1 つのフィールドのみで問題なく機能する単純なクエリがありました。

関数を使用したライブ検索のため、onkeyupいくつかの問題を認識しました。私が説明する必要がある最初の問題:

テーブルの構造は非常に単純です。zipcode | city

たとえば、誰かが入力し12345ます。もちろん、これは郵便番号です。しかし、誰かが入力した場合12345 hometown、最初のキーワードが郵便番号で、2 番目が都市になる場合はどうなるでしょうか。

キーワードは を使用して分割される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");
...

さて、これまでのところとても良いです。問題は、キーワードが各フィールドに何度も一致する可能性があることです。

さらに例を挙げると:

上記の入力の場合、フィールドORに 一致できる12345 hometownことを意味します。この条件は、フィールドORに一致する場合でも、と同等です。ですから、逆に入っても同じ意味です。key[0] => 12345zipcodecitykey[1] => hometownzipcodecityhometown 12345

そして、これが私が最初に抱えた問題です。

クエリを構成するロジックを探しています。したがって、入力する場合は、次の12345 hometownようなものが必要です。

key[0] => 12345フィールドが一致する場合、それがORで一致するかどうかをzipcode確認しないでください。一致する必要があるのは非常に論理的であるためです。key[1] => hometownzipcodecitykey[0]zipcodekey[1]city

アップデート

さて、私の 2 番目の問題を説明するdavid strachan ために、都市に複数の文字列が含まれている場合に問題が発生すると彼は言いました。検索文字列が次のようになるとします。

12345 New York

キーは次のとおりです。

key[0] => 12345, key[1] => New, key[2] => York

さて、問題は、キーの1つに整数が含まれているかどうかを確認でき、文字列の長さが正確に5の場合、それが郵便番号になることがわかっていることです。

key[0] => 12345 //if ( stringlen(key[0|) === 5) === true  && is_int(key[0]) === true) {zipcode}

ここまでは順調ですが、本当の問題は、都市の文字列の背後にあるロジックです。最初に考えたのは、整数を含まないすべてのキーは都市でなければならないので、それらを 1 つのキーに変換できるということでした。

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]);}

わかりましたが、将来通りの名前を追加したい場合はどうすればよいですか? 通りの名前や都市名を分離してテストする方法がわかりません。

4

2 に答える 2

1

もう 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>

提案.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;

デモ

于 2013-04-16T20:49:01.710 に答える
0

$search_term[0]0 を追加して string(city) か 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;

問題の 1 つは、ニューヨークをどのように扱うかです。これを解決する方法はお任せします。

編集

ニューヨーク$total_search_terms > 2

于 2013-04-14T16:05:40.197 に答える