我正在为应用开发API,并且优惠结果需要过滤,例如:
Filters
Price Min - Price Max
Category Ids
Min Review (1-5 stars) if 3 is sent then only 3 and above
Min Distance
Max Distance
Location (for the above 2)
Sort By
Distance,
Price,
Review
我对最有效的方法感到困惑,我将发布用户过滤器选项,但根据他们的选项执行查询是让我失去的部分。
任何帮助都会受到大力赞赏!谢谢大家:))
答案 0 :(得分:3)
当您开始对查询应用条件时,您需要注意以下功能:newQuery()
。此功能允许您启动新的查询构建器并将过滤器/顺序链接到其上。
示例架构:
产品表中的列:
id | name | price | date_received
product_tag 表中的列:
id | tag_id | product_id
标记表中的列:
id | name
<强>关系:强>
我不会设置雄辩的模型,但请注意,产品型号的tag()
功能与hasManyThrough()
关系
已设置过滤器类,主要目的是应用过滤器和放大器。订购。注意:该类可以进一步抽象化。
您的过滤器类:
class ProductFilter {
/**
* Fluent query builder
* @var mixed $queryBuilder
*/
private $queryBuilder;
/**
* Http Request
* @var \Illuminate\Http\Request $request
*/
protected $request;
/**
* Filters collection
* @var array $filters
*/
private $filters = [];
/**
* Order Bys Collection
* @var array $orderBys
*/
private $orderBys = [];
/**
* Class constructor
*
* @param array $input
*/
public function __construct(\Illuminate\Http\Request $request, &$queryBuilder)
{
//Initialize Query Builder
$this->queryBuilder = $queryBuilder;
//Get input
$this->request = $request;
//Register Filters
$this->registerFilters();
//Register Order Bys
$this->registerOrderBys();
}
/**
* Register Filters in the function below
* Each filter is in the form of an array
*/
private function registerFilters()
{
$this->filters['product_name'] = ['name'=>'Name',
'value' => $this->request->get('filter_product_name'),
'enabled' => $this->request->has('filter_product_name'),
'function' => 'filterProductName'
];
$this->filters['tag'] = ['name'=>'End Date',
'value' => $this->request->get('filter_tag'),
'enabled' => $this->request->has('filter_tag'),
'function' => 'filterTag'
];
}
/**
* Check if any filters are active
* Useful to show/hide filter bar
*
* @return bool
*/
public function isFiltersActive()
{
return (boolean)count(
array_filter($this->filters,function($v){
return $v['enabled'] === true;
})
);
}
/**
* Register Order Bys in the function below
* Each order by is in the form of an array
*
*/
private function registerOrderBys()
{
$this->orderBys['name'] = [
'name' => 'Order By Name',
'value' => $this->request->get('order_by_product_name','ASC'),
'enabled' => $this->request->has('order_by_product_name'),
'function' => 'orderByProductName'
];
}
/**
* Check if any order bys are active
* Useful to show/hide order by bar
*
* @return bool
*/
public function isOrderBysActive()
{
return (boolean)count(
array_filter($this->orderBys,function($v){
return $v['enabled'] === true;
})
);
}
/**
* Apply Filters
* Loop through each filter, check if they are enabled. If they are, apply filter to query builder
*/
public function applyFilters()
{
foreach($this->filters as $filter_name => $filter_array)
{
if($filter_array['enabled'] &&
array_key_exists('function',$filter_array) &&
method_exists($this,$filter_array['function']))
{
$this->{$filter_array['function']}($filter_array);
}
}
return $this;
}
/**
* Apply Order Bys
* Loop through each order by, check if they are enabled. If they are, apply order by to query builder
*/
public function applyFilters()
{
foreach($this->orderBys as $order_by_name => $order_by_array)
{
if($order_by_array['enabled'] &&
array_key_exists('function',$order_by_array) &&
method_exists($this,$order_by_array['function']))
{
$this->{$order_by_array['function']}($order_by_array);
}
}
return $this;
}
/*
* Filter Functions: START
*/
/**
* Filter by Product Name
*
* @param array $filterArray
*/
private function filterProductName($filterArray)
{
$this->queryBuilder
->where('name','=',$filterArray['value']);
}
/**
* Filter by Product Tag
*
* @param array $filterArray
*/
private function filterTag($filterArray)
{
$this->queryBuilder
->whereHas('tag',function($query) use ($filterArray){
return $query->where('name','=',$filterArray['value']);
});
}
/*
* Filter Functions: END
*/
/*
* Order By Functions: START
*/
/**
* Order By Name
* @param array $orderByArray
*/
private function orderByName($orderByArray)
{
$this->queryBuilder
->orderBy('name', $orderByArray['value']);
}
/*
* Order By Functions: END
*/
}
使用方法:
//In my controller function
public function getListOfProducts(\Illuminate\Http\Request $request)
{
//Init Product Query
$productQuery = \App\Models\Product()::newQuery();
//Apply all filters and order bys
$productFilter = app('ProductFilter',[$request,$productQuery])->applyFilters()->applyOrderBys();
//Fetch Product Result
$productResult = $productQuery->get();
}