优化在laravel中使用ElasticSearch的代码
在App\Support目录下创建一个GoodsEsBuilder的类,这个类就用于对es商品搜索的查询条件的生成器
因为参数的格式基本一致,所以我们可以定义如下格式
然后提供如下图中的几个方法
分别对于是category根据商品分类查询,getParams获取查询格式,keywords根据关键词查询,orderby排序,paginate 分页,sale是否上架
// 添加分页查询
public function paginate($size, $page)
{
$this->params['body']['from'] = ($page - 1) * $size;
$this->params['body']['size'] = $size;
return $this;
}
// 筛选上架状态的商品
public function sale()
{
$this->params['body']['query']['bool']['filter'][] = ['term' => ['sale' => 1]];
// ['term' => ['sale' => 1]],
return $this;
}
// 按类目筛选商品
public function category(GoodsCategory $category)
{
if ($category->level != 2) {
$this->params['body']['query']['bool']['filter'][] = [
'prefix' => ['category_path' => $category->possess.$category->id.'-'],
];
} else {
$this->params['body']['query']['bool']['filter'][] = ['term' => ['category_id' => $category->id]];
}
}
// 添加搜索词
public function keywords($keywords)
{
// 如果参数不是数组则转为数组
$keywords = is_array($keywords) ? $keywords : [$keywords];
foreach ($keywords as $keyword) {
$this->params['body']['query']['bool']['must'][] = [
'multi_match' => [
'query' => $keyword,
'fields' => [
'title^3',
'long_title^2',
'category^2', // 类目名称
'desc',
'skus_attr_name',
],
],
];
}
return $this;
}
// 添加排序
public function orderBy($field, $direction)
{
if (!isset($this->params['body']['sort'])) {
$this->params['body']['sort'] = [];
}
$this->params['body']['sort'][] = [$field => $direction];
return $this;
}
// 返回构造好的查询参数
public function getParams()
{
return $this->params;
}
如上代码
修改控制器:
$page = $request->input('page', 1);
$perPage = 6;
// 新建查询构造器对象,设置只搜索上架商品,设置分页
$builder = (new GoodsEsBuilder())->sale()->paginate($perPage, $page);
if ($request->input('category_id') && $category = GoodsCategory::find($request->input('category_id'))) {
// 调用查询构造器的类目筛选
$builder->category($category);
}
if ($search = $request->input('search', '')) {
$keywords = array_filter(explode(' ', $search));
// 调用查询构造器的关键词筛选
$builder->keywords($keywords);
}
$builder->orderBy('pv', 'desc');
// 最后通过 getParams() 方法取回构造好的查询参数
return app('es')->search($builder->getParams());