基于数据库列的记录过滤使用自动完成搜索PHP无法正常工作

时间:2015-03-05 21:58:03

标签: php mysql search full-text-search full-text-indexing

我在我的网站中集成了自动完成搜索,用户输入关键字并根据它查看记录。

假设,如果我编写邮政编码,它只会过滤来自zip字段的数据。接下来,如果用户类型地址如121 North West,那么脚本会自动选择与西北121匹配的记录。此外,对于街道来说,如果用户类型街道名称如雪松车道,则只从数据库字段街道提取记录。

我遇到问题,它搜索所有字段的记录,因此我无法从数据库中获取正确的列表。

我关注的Referense网站是http://www.trulia.com,这是按预期工作的。我希望在我的网站上使用相同的内容,但它的工作原理却不像我预期的那样。

我的PHP代码:

<?php
$searchKeyword  = $_REQUEST['keyword'];

$searchQ    =   "SELECT zip, ste, st, st_num, town, addr FROM tbl_property WHERE (zip = '$searchKeyword' OR ste like '%$searchKeyword%' OR town like '%$searchKeyword%' OR addr like '%$searchKeyword%') GROUP BY zip LIMIT 0,5";
$queryRec   = mysql_query($searchQ);
$recSet     = mysql_num_rows($queryRec);
echo "<div id='fetchRecs'><ul>";
if($recSet>0){
    while($row = mysql_fetch_array($queryRec)) { 
        echo '<li>'.$row['addr'].', '.$row['town'].', '.$row['ste'].', '.$row['zip'];?></li>
    <?php
            }
        }else{
    echo "<li>No Records Found</li>";       
    }
echo "</ul></div>";

我只想要用户写入123,列表显示为1234,1245,以及类似列表仅显示zip列的邮政编码。

同样,如果用户写123雪松,它选择类似于123雪松的列表只意味着它将来自街道列。

P.S:我只有一个文本字段,我在其中输入关键字:http://www.trulia.com

P.S:我的问题仍然没有解决,如果有人有任何有用的信息,请分享。可能它也适用于其他一些人。

3 个答案:

答案 0 :(得分:0)


已更新


这是http://www.trulia.com/

的表格
<div class="searchbox">
  <form id="searchbox_form" class="searchbox_form form man" method="get" action="/submit_search/" autocomplete="off">
    <div class="field man">

      <span class="select">
        <div id="homepage-select" class="selectPretty">
          <select id="search_options" class="h5 man txtL" name="display_select" data-previous-selection="for_sale">
              <option value="for_sale">Buy</option>
              <option value="for_rent">Rent</option>
              <option value="sold">Recently sold</option>
          </select>
          <div class="selectDisplay btn btnLrg btnDefault rrn backgroundBasic pts plm">
            <span class="selectLabel h5">Buy</span>
            <span class="selectTrigger pts"><i class="iconDownOpen"></i></span>
          </div>
        </div>
      </span>
      <span class="text">
        <div style="display: none; top: 129px; left: 297.5px; width: 370px;" class="autosuggest_list"><ul><li class="location-get-me">Current Location</li></ul></div><input id="searchbox_form_location" type="text" name="search" class="searchbox_form_location searchInput text searchByLocation typeWeightNormal h5 man" value="" placeholder="Search by neighborhood, city, zip or address" autocomplete="off">
        <input type="hidden" name="locationId" value="">
        <input type="hidden" name="locationType" value="">
        <input type="hidden" name="tst" class="searchbox_form_type" value="h">
        <input type="hidden" name="ac_entered_query" value="">
        <input type="hidden" name="ac_index" value="">
        <input type="hidden" name="propertyId" value="">
        <input type="hidden" name="propertyIndex" value="">
        <input type="hidden" name="display" class="searchbox_form_type_display" value="for sale">
        <button class="btn btnPrimary submit"><span class="h5 typeEmphasize"><i class="iconSearch h4"></i>SEARCH</span></button>
      </span>
    </div>
  </form>
</div>

如果你过滤了页面制作的GET请求,你可以在文本bax中插入一个json请求ajax:

{
    "locations": [{
        "value": "47977",
        "altValue": null,
        "display": "19901",
        "type": "zipCode",
        "propertyIndex": "",
        "index": 0
    }, {
        "value": "47978",
        "altValue": null,
        "display": "19902",
        "type": "zipCode",
        "propertyIndex": "",
        "index": 1
    }, {
        "value": "47979",
        "altValue": null,
        "display": "19903",
        "type": "zipCode",
        "propertyIndex": "",
        "index": 2
    }, {
        "value": "47980",
        "altValue": null,
        "display": "19904",
        "type": "zipCode",
        "propertyIndex": "",
        "index": 3
    }, {
        "value": "47981",
        "altValue": null,
        "display": "19905",
        "type": "zipCode",
        "propertyIndex": "",
        "index": 4
    }],
    "suggestions": [],
    "success": true,
    "errors": []
}

类似于我第一次给你的最后一个例子(使用ajax为你的搜索设置一个隐藏的vaule输入),然后在你的php文件中你可以切换为隐藏的输入值,在json中是{{ 1}}

您可以使用这些附加信息再次阅读最后一种方法。

如果我弄错了,请告诉我,我希望这会对你有所帮助。


如果您希望获得客户将搜索的每种搜索类型的分区列表,您可以输入另一个输入来引用搜索类型:

"type": "zipCode"

然后在你的PHP代码中:

<select name="field">
    <option value="zip">Zip Code</option>
</select>
<input type="text" name="keyword" />

根据客户搜索的内容,这将为您提供一个单独的列表。

其他形式的做法是分析关键字中的数据,例如,您知道如果您只有1个单词也可以转换为数字,那么它指的是邮政编码

你可以使用数组:

$field = $_REQUEST['field'];
$keyword = $_REQUEST['keyword'];
$query = "SELECT * FROM tbl_property";
$where = "";
switch ($field) {
    case 'zip':
        $where = " WHERE zip = " . $keyword;
        break;
    case 'addr':
        $where = " WHERE addr like " . $keyword . "%";
        break;
    case 'city':
        $where = " WHERE city like " . $keyword . "%";
        break;
}
$query = $query . $where . " GROUP BY zip LIMIT 0,5";

这取决于你自己的逻辑。

如果我弄错了,请告诉我,我希望这会对你有帮助。


MOD 03/05/2015 8:00:00 p.m。

您还可以使用javascript和ajax获取您拥有的城市,邮政编码和地址列表,并在隐藏的输入中设置您将进行的搜索类型。例如,使用jQuery:

$keyword = $_REQUEST['keyword'];
$query = "SELECT * FROM tbl_property";
$where = "";
$parms = split(" ", $keyword);
if(count($parms) == 1 && intval($parms[0], 10) > 0){
    $where = " WHERE zip = " . $keyword;
}elseif (count($parms) > 1){
    $where = " WHERE addr like %" . $keyword . "%";
}

on req.php

<input type="text" name="keyword" id="keyword"           />
<input type="hidden" name="field" id="field" value="all" />
<div id="lists"></div>

<script>
    $('#keyword').change(function() {
        $.ajax({
            type: "POST",
            url: "req.php",
            data:{ key: $(this).val() },
            success: function(data){
                $('#lists').html(data);
            }
        });
    });
    $('#lists ul li').click(function(){
        $('#keyword').val($(this).html());
        $('#field').val($(this).parent().data('field'));
    });
</script>

如果我没有错过任何东西它应该有用。

如果我弄错了,请告诉我,我希望这会对你有所帮助。

答案 1 :(得分:0)

您必须定义策略,您可以使用JSON,例如网络www.trulia.com,或者html响应等。

你的html文件,使用json方法,记得定义你自己的逻辑!:

<input type="text" name="keyword" id="keyword" />
<input type="hidden" name="field" id="field" value="all" />
<div id="lists"></div>

<script>
    $('#keyword').change(function() {
        $.ajax({
            type: "POST",
            url: "req.php",
            data:{ key: $(this).val() },
            success: function(data){
                //Show the data to the clients
                //(in a div or a "select2" plugin)
                $.each(data.locations, function( key, value ) {
                    //iterate over locations
                }

                //SetUp hidden default value while keyword change
                //Form the JSON Response
                $('#field').val(data.locations[0].type); //Get the type of the first element in locations
            }
        });
    });
    $('#lists ul li').click(function(){
        $('#keyword').val($(this).html());
        $('#field').val($(this).parent().data('field'));
    });
</script>

req.php文件:

$key = $_POST['key'];

$data = array(
              'locations' => array(),
              'errors'=>array(),
              'success': true,
              );

header('Content-Type: application/json');

$db = new mysqli('localhost', 'user', 'pass', 'db');

if($db->connect_errno > 0){
    $data['errors'][] = $db->connect_error;
    die(json_encode($data));
}

$query = "SELECT zip FROM tbl_property WHERE zip like " . $key . "%;";
if(!$zips = $db->query($sql)){
    $data['errors'][] = $db->connect_error;
    die(json_encode($data));
}

$query = "SELECT city FROM tbl_property WHERE city like " . $key . "%;";
if(!$cities = $db->query($sql)){
    $data['errors'][] = $db->connect_error;
    die(json_encode($data));
}

$index = 0;

while($row = $zips->fetch_assoc()){
    $data['locations'][] = array(
        "value": $row['zip'],
        "altValue": null,
        "display": $row['zip'],
        "type": "zipCode",
        "propertyIndex": "",
        "index": $index
    );

    $index = $index + 1
}

while($row = $cities->fetch_assoc()){
    $data['locations'][] = array(
        "value": $row['city'],
        "altValue": null,
        "display": $row['city'],
        "type": "city",
        "propertyIndex": "",
        "index": $index
    );

    $index = $index + 1
}

$db->close();

header('Content-Type: application/json');
echo json_encode($data);

在trulia.com中的JSON响应:

{
    "locations": [{
        "value": "47977",
        "altValue": null,
        "display": "19901",
        "type": "zipCode",
        "propertyIndex": "",
        "index": 0
    }, {
        "value": "47978",
        "altValue": null,
        "display": "19902",
        "type": "zipCode",
        "propertyIndex": "",
        "index": 1
    }, {
        "value": "47979",
        "altValue": null,
        "display": "19903",
        "type": "zipCode",
        "propertyIndex": "",
        "index": 2
    }, {
        "value": "47980",
        "altValue": null,
        "display": "19904",
        "type": "zipCode",
        "propertyIndex": "",
        "index": 3
    }, {
        "value": "47981",
        "altValue": null,
        "display": "19905",
        "type": "zipCode",
        "propertyIndex": "",
        "index": 4
    }],
    "success": true,
    "errors": []
}

在您的搜索php文件中(用户提交时将搜索的文件)

$field = $_REQUEST['field'];
$keyword = $_REQUEST['keyword'];
$query = "SELECT * FROM tbl_property";
$where = "";
switch ($field) {
    case 'zip':
        $where = " WHERE zip = " . $keyword;
        break;
    case 'addr':
        $where = " WHERE addr like " . $keyword . "%";
        break;
    case 'city':
        $where = " WHERE city like " . $keyword . "%";
        break;
}
$query = $query . $where . " GROUP BY zip LIMIT 0,5";

$db = new mysqli('localhost', 'user', 'pass', 'db');
$result = $db->query($query);

// show the result

$db->close();

如果我没有错过任何它应该有效。

如果我弄错了,请告诉我,我希望这会对你有所帮助。

答案 2 :(得分:0)

首先,请留意我的错误。

好的,我改变了一些事情,现在正在努力:

//Filter:
<?php

  if (isset($_REQUEST['field']) && isset($_REQUEST['keyword'])) {
    $field = $_REQUEST['field'];
    $keyword = $_REQUEST['keyword'];
  }else{
    $field = null;
    $keyword = null;
  }
  $query = "SELECT * FROM tbl_property";
  $where = "";
  switch ($field) {
      case 'zipCode':
          $where = " WHERE zip like '" . $keyword . "%'";
          break;
      case 'addr':
          $where = " WHERE addr like " . $keyword . "%";
          break;
      case 'city':
          $where = " WHERE city like " . $keyword . "%";
          break;
  }
  $query = $query . $where;

  $db = new mysqli('localhost', 'user', 'password', 'db');
  if ($db->connect_errno > 0){
    die($db->connect_error);
  }

  $result = $db->query($query)
?>

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Searcher</title>
  <link rel="stylesheet" href="">
</head>
<body>

    <section id="searcher">
      <form action="" method="post">
      <input type="text" name="keyword" id="keyword"           />
      <input type="hidden" name="field" id="field" value="all" />
      <div id="lists">
        <ul></ul>
      </div>
      </form>
    </section>

    <section id="results">
        <table>
          <caption>Results</caption>
          <thead>
            <tr>
              <th>Zip</th>
              <th>Address</th>
              <th>City</th>
            </tr>
          </thead>
          <tbody>
            <?php while($row = $result->fetch_assoc()){ ?>
            <tr>
              <td><?php echo ($row['zip']); ?></td>
              <td><?php echo ($row['addr']); ?></td>
              <td><?php echo ($row['city']); ?></td>
            </tr>
            <?php } ?>
          </tbody>
        </table>      
    </section>

    <script src="http://code.jquery.com/jquery-2.1.3.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript">
      $( "#keyword" ).keyup(function() {
        $.ajax({
            type: "POST",
            url: "req.php",
            data:{ key: $(this).val() },
            success: function(data){
                //Show the data to the clients
                //(in a div or a "select2" plugin)
                if (data.locations.length > 0){
                  $('#lists ul').html('');
                  $.each(data.locations, function( key, location ) {
                      //iterate over locations
                      $('#lists ul').append( '<li data-field="' + location._type + '">' + location.value  + '</li>' );
                  });

                  //SetUp hidden default value while keyword change
                  //Form the JSON Response
                  $('#field').val(data.locations[0]._type);
                }else{
                  $('#lists ul').html('No Results!');
                  $('#field').val('all');
                }
            }
        });
      });

      $('#lists ul li').click(function(){
          $('#keyword').val($(this).html());
          $('#field').val($(this).parent().data('field'));
      });
    </script>

</body>
</html>

<?php
  $db->close();
?>

//req.php
<?php
$key = $_POST['key'];

$data = array(
              'locations' => array(),
              'errors'=>array(),
              'success'=> true
              );

header('Content-Type: application/json');

  $db = new mysqli('localhost', 'user', 'password', 'db');

if($db->connect_errno > 0){
    $data['errors'][] = $db->connect_error;
    die(json_encode($data));
}

$query = "SELECT zip FROM tbl_property WHERE zip LIKE '" . $key . "%';";
$zips = $db->query($query);

$query = "SELECT city FROM tbl_property WHERE city LIKE '" . $key . "%';";
$cities = $db->query($query);

if($db->connect_errno > 0){
    $data['errors'][] = $db->connect_error;
    die(json_encode($data));
}

$index = 0;
if ($zips){
  while($row = $zips->fetch_assoc()){
      $data['locations'][] = array(
          "value"=> $row['zip'],
          "altValue"=> null,
          "display"=> $row['zip'],
          "_type"=> "zipCode",
          "propertyIndex"=> "",
          "index"=> $index
      );
      $index = $index + 1;
  }
}
if ($cities){
  while($row = $cities->fetch_assoc()){
      $data['locations'][] = array(
          "value"=> $row['city'],
          "altValue"=> null,
          "display"=> $row['city'],
          "type"=> "city",
          "propertyIndex"=> "",
          "index"=> $index
      );

      $index = $index + 1;
  }
}

$db->close();

header('Content-Type: application/json');
echo json_encode($data);

我没有对lists ul li元素上的点击事件进行测试,因为我不知道你会做什么,而且不太重要。

我希望那就是你在寻找的东西。 保持联系。