Laravel 4 - 产品搜索服务

时间:2014-12-09 14:32:30

标签: php mysql laravel

这是我第一次尝试构建搜索服务。问题是我的代码看起来非常不整洁,这可能会导致将来出现其他问题。这是我到目前为止所写的内容:

<?php namespace Acme\Services\Search;
use Product, Brand;

class ProductSearchService {
 public function search($data = array()) {
 $limit     = 10;
 $query     = isset($data) ? $data : "";
 $baseQuery = Product::take($limit);

 $brand = Brand::where('name', 'LIKE', '%'.$query.'%')->first();

 if($query) {
  if (!empty($brand)) {
    return $baseQuery
        ->where('name', 'LIKE', '%'.$query.'%')
        ->orWhere('description', 'LIKE', '%'.$query.'%')
        ->orWhere('brand_id', 'LIKE', '%'.$brand->id.'%')->get();
  }

    return $baseQuery
      ->where('name', 'LIKE', '%'.$query.'%')
      ->orWhere('description', 'LIKE', '%'.$query.'%')->get();
    }
  }
}

我应该如何构建此服务以使其更清洁并返回更准确的结果?

解决方案

这里发布的答案非常有用,但我找到了另一个解决方案。

我使用了预先加载来减少查询数量并声明了一个基本查询,如下所示:

  $products = Product::with('brand')
              ->where('name','LIKE','%'.$term.'%');

然后我使用orWhereHas方法搜索任何相关品牌,例如:

  $products->orWhereHas('brand', function($q) use ($term) {
      $q->where('name', 'like', '%'.$term.'%');
  });

然后返回$products->get()

2 个答案:

答案 0 :(得分:1)

为你重写了它,请注意这还不完美,同时使用LIKE作为brand_id并不是一个非常聪明的想法因为id是独一无二的!这也意味着也不需要搜索名称和描述。你应该在获得id时搜索id,如果没有,则执行2 LIKE查询。

<?php 

    namespace Acme\Services\Search;

    use Product, Brand;

    class ProductSearchService {

        public function search($data = array()) {
            $limit = 10;
            $query = isset($data) ? $data : "";

            $baseQuery = Product::take($limit);

            $brand = Brand::where('name', 'LIKE', '%'.$query.'%')->first();

            $brandId = !empty($brand) ? $brand->id : "";

                return $baseQuery->where('name', 'LIKE', '%'.$query.'%')
                                 ->orWhere('description', 'LIKE', '%'.$query.'%')
                                 ->orWhere('brand_id', 'LIKE', '%'.$brand_id.'%')->get();
        }

    }

?>

答案 1 :(得分:1)

这是我的尝试

<?php namespace Acme\Services\Search;

use Product, Brand;

class ProductSearchService {
    public function search($query) {

        $limit     = 10;

        $brand = Brand::where('name', 'LIKE', '%'.$query.'%')->first();

        $baseQuery = Product::take($limit)
                ->where('name', 'LIKE', '%'.$query.'%')
                ->orWhere('description', 'LIKE', '%'.$query.'%');

        if (!empty($brand))
        {
            $baseQuery = $baseQuery->orWhere('brand_id', 'LIKE', '%'.$brand->id.'%')->get();
        }

        return $baseQuery->get();
    }
}