基于多级过滤器Mysql+PHP优化搜索结果
我正在尝试创建一个多层次的搜索,允许用户根据品牌、产品类别和价格范围对相同的搜索进行细化 以下实现可能无法正常工作,因为我只是提供了一种方法来说明我的问题 表: 产品 价格范围基于多级过滤器Mysql+PHP优化搜索结果,php,mysql,search,filter,filtering,Php,Mysql,Search,Filter,Filtering,我正在尝试创建一个多层次的搜索,允许用户根据品牌、产品类别和价格范围对相同的搜索进行细化 以下实现可能无法正常工作,因为我只是提供了一种方法来说明我的问题 表: 产品 价格范围 | id | price_from | price_to | | 1 | 100 | 200 | | 1 | 200 | 300 | 产品属性 | product_id | id_attribute | | 1
| id | price_from | price_to |
| 1 | 100 | 200 |
| 1 | 200 | 300 |
产品属性
| product_id | id_attribute |
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 1 | 5 |
| 2 | 5 |
| 2 | 3 |
| 3 | 5 |
| id | name |
| 1 | attr1 |
| 2 | attr2 |
| 3 | attr3 |
| 4 | attr4 |
| 5 | attr5 |
| 6 | attr6 |
| 7 | attr7 |
属性
| product_id | id_attribute |
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 1 | 5 |
| 2 | 5 |
| 2 | 3 |
| 3 | 5 |
| id | name |
| 1 | attr1 |
| 2 | attr2 |
| 3 | attr3 |
| 4 | attr4 |
| 5 | attr5 |
| 6 | attr6 |
| 7 | attr7 |
我正在通过$\u GET传递url中的参数。我的多过滤器搜索代码如下所示:
//this generates the base query
$dynamicsql = get_by_filters();
//does the group by to discard duplicated products
$filtersql= $dynamicsql."group by p.id";
$query = mysql_query($filtersql) or die(mysql_error());
//the data is now ready to be presented but
$total = mysql_num_rows($query);
for($i=0; $i<$total; $i++):
$prods[$i] = mysql_fetch_object($query);
endfor;
//first let's build the html code for filtering the results
list_prices_filter($dynamicsql);
//i'll only show the code for the bellow function. the above is pretty similar
list_attr_filter($dynamicsql);
//now i print the results
foreach($prods as $prod):
//for the porpuse of this question will only print the product name
echo $prod['pname'];
endforeach;
列出属性选择的函数:
function get_special_care($dynamicsql){
$sql = "SELECT * FROM attributes a";
$query = mysql_query($sql);
$total = mysql_num_rows($query);
$output = '<ul>';
for($i=0; $i<$total;$i++):
$result[$i] = mysql_fetch_object($query);
$active = ($_GET['attr'] == $result[$i]->uid) ? 'active':'';
$workerstotal = mysql_query($dynamicsql . " and a.id ={$result[$i]->uid} group by p.id");
$totalworkers = mysql_num_rows($workerstotal);
$output .= '
<li class="'.$active.'">
<a href="'.url_increment('attr='.$result[$i]->uid).'">'.$result[$i]->name.'<span class="totalfound">('.$totalworkers.')</span></a>
<a title="Remove" href="'.url_decrement('attr').'" class="remove-criteria"><img src="'image_src_url" alt="Remove" /></a>
</li>';
endfor;
$output .= '</ul>';
echo $output;
}
但我不知道怎么解决这个问题
这段代码还有另一个问题,因为一旦您第一次选择了属性,url看起来像www.teste.com/search&attr=5。第二次单击后,假设用户单击属性1,url将是www.teste.com/search&attr=5&attr=1,我认为这也是一个问题
有人能帮忙吗?我相信你们中的许多人已经实现了类似的算法,如果你能帮上忙,那就太好了
最后,对于这篇冗长的帖子,我很抱歉,但我想解释一下我自己,也许它可以作为今后帮助的参考
提前谢谢 到目前为止,我能发现的唯一错误是
case 'price': $dynamicsql .= " AND p.price = ".$value;
p、 价格参考products.price,其中在原产地产品表中没有价格字段
是否存在任何查询异常 我设法解决了这个问题,如下所示: 创建了一个函数,用于从url normal$\u get['name']ony获取所有属性,返回url中的attribute=5,如www.test.com/?mod=search&attribute=2&attribute=5
function getFilter(){
$query = explode('&', $_SERVER['QUERY_STRING']);
$params = array();
foreach( $query as $param )
{
list($name, $value) = explode('=', $param);
$params[urldecode($name)][] = urldecode($value);
}
return $params;
}
然后我改变了函数get_by_过滤器
function get_by_filters(){
$dynamicsql = "SELECT p.name as pname,p.price_from,p.price_to,a.name,a.id FROM `products` p ";
$dynamicsql .= "left JOIN `price_ranges` pr ON p.price_id = pr.id ";
$dynamicsql .= "LEFT JOIN `product_attributes` pa ON w.id = pa.product_id ";
$dynamicsql .= "LEFT JOIN `attributes` a ON a.uid = pa.id_attribute where 1=1 ";
foreach($_GET as $parameter=>$value):
switch($parameter):
case 'price':
$dynamicsql .= " AND p.price = ".$value;
break;
//changes here
case 'attr':
$get = tools::getFilter();
foreach ($get['attr'] as $attrs => $value) {
$filter .= " and w.uid in (select a from `product_attributes` where attribute_id= {$value}) ";
}
default:
$dynamicsql .= "AND ".$parameter." = ".$value." ";
break;
endswitch;
endforeach;
return $dynamicsql;
}
最后,我们必须展示所有活动属性过滤器,因此我更改了此函数,如下所示:
function get_special_care($dynamicsql){
$sql = "SELECT * FROM attributes a";
$query = mysql_query($sql);
$total = mysql_num_rows($query);
//changes here
$get = tools::getFilter();
$output = '<ul>';
for($i=0; $i<$total;$i++):
$result[$i] = mysql_fetch_object($query);
//changes here
foreach ($get['attr'] as $attr => $value) {
$active = ($value == $result[$i]->uid) ? 'active':$active;
}
$workerstotal = mysql_query($dynamicsql . " and a.id ={$result[$i]->uid} group by p.id");
$totalworkers = mysql_num_rows($workerstotal);
$output .= '
<li class="'.$active.'">
<a href="'.url_increment('attr='.$result[$i]->uid).'">'.$result[$i]->name.'<span class="totalfound">('.$totalworkers.')</span></a>
<a title="Remove" href="'.url_decrement('attr').'" class="remove-criteria"><img src="'image_src_url" alt="Remove" /></a>
</li>';
endfor;
$output .= '</ul>';
echo $output;
}
您好,请尝试在运行时回显所有查询,以帮助您了解函数的实际情况。它对复杂的sql生成算法有很大帮助。例如,回显所有url属性和sql。所以输出就像url属性一样,sql在那里是Hi!!谢谢你的回复。我已经这样做了,我发现问题似乎在这里$dynamicsql.=和a.id=.$value;因为我基本上告诉sql只返回与该属性\u id相关联的结果,但问题是我无法更改sql以匹配我想要的内容…您介意在运行get\u special\u care$dynamicsql时向我显示查询吗抱歉,该行应该显示function list\u attr\u filter$dynamicsql。无论如何,我正在更改原始帖子以更正错误并提供查询返回。感谢您将echo$dynamicsql放在foreach$\u GET as$parameter=>$value:后面,以便在运行url时为我提供最终查询。从db向后工作比跳进php代码要容易一些。您好!!那也是一个打字错误。我的实际代码要复杂得多,可能会造成巨大的混乱。很抱歉。
function get_special_care($dynamicsql){
$sql = "SELECT * FROM attributes a";
$query = mysql_query($sql);
$total = mysql_num_rows($query);
//changes here
$get = tools::getFilter();
$output = '<ul>';
for($i=0; $i<$total;$i++):
$result[$i] = mysql_fetch_object($query);
//changes here
foreach ($get['attr'] as $attr => $value) {
$active = ($value == $result[$i]->uid) ? 'active':$active;
}
$workerstotal = mysql_query($dynamicsql . " and a.id ={$result[$i]->uid} group by p.id");
$totalworkers = mysql_num_rows($workerstotal);
$output .= '
<li class="'.$active.'">
<a href="'.url_increment('attr='.$result[$i]->uid).'">'.$result[$i]->name.'<span class="totalfound">('.$totalworkers.')</span></a>
<a title="Remove" href="'.url_decrement('attr').'" class="remove-criteria"><img src="'image_src_url" alt="Remove" /></a>
</li>';
endfor;
$output .= '</ul>';
echo $output;
}