【问题标题】:Laravel ORM filter with many to many relationship具有多对多关系的 Laravel ORM 过滤器
【发布时间】:2016-03-12 03:47:50
【问题描述】:

我正在按公司和/或类别进行搜索。 输出应该是上市公司,每个公司输出一个或多个类别。

表“公司”

身份证名称

1 公司 1 2 公司 2 3 公司 3

表“类别”

身份证名称

1 托管 2 域 3 硬件

列出所有结果

  1. 公司 1,(类别 = 托管、域)
  2. 公司 2,(类别 = 域硬件)
  3. 公司 3,(类别 = 硬件托管)

现在我的问题是如何构建 ORM 查询以便过滤类别?按公司过滤很容易实现,但我坚持按类别过滤。

例如我希望达到的输出。

过滤域,输出

  1. 公司 1,(类别 = 托管、域)
  2. 公司 2,(类别 = 域硬件)

公司条目大约 20k 行,而类别 1k+ 行。

测试失败

此查询耗时过长,并且也会占用处理器。

$companies = Companies
        ::with(['categories'=>function($q)use($category){
            if (isset($category)){
                $q->where('slug','=',$category->slug);
            }
        }])->paginate(20);

此查询时,仅过滤公司模式内的类别。

$companies = Companies::whereHas('categories',function($q)use($category){
            $q->where('categories.id','=',$category->id);
        })
        ->paginate(20);

有两种模式

公司

public function categories(){
    return $this->belongsToMany('App\Models\Categories','companies_categories','company_id','category_id');
}

类别

public function companies(){
    return $this->belongsToMany('App\Models\Companies','companies_categories','category_id','company_id');
}

【问题讨论】:

    标签: laravel laravel-5


    【解决方案1】:

    你可以这样做:

    $companies = Company::has('categories')->get();
    

    结果将是至少拥有一个类别的公司。我想这就是你要找的。​​p>

    【讨论】:

      【解决方案2】:

      由于您使用的是 Laravel,这将很容易。在您的代码中,所有处理(过滤)都由数据库服务器完成,因此需要太多时间,但还有另一种方法。

      只需使用获取所有记录 Companies::with('categories')->get(); 这将为您提供Collection 对象,您可以以任何您想要的方式处理/过滤它。您可以使用where, orderBy, sortBy 类型的函数,这些函数在您上面的数据库服务器处理的代码中现在可以由服务器处理,而且还有更多可用的函数。

      【讨论】:

      • 也试过这个方法。但是它占用了资源并且需要超过 2 分钟才能返回。因为记录是 20k 公司和 1k 类别....
      • 如果这些记录没有变化,那么您可以使用redis 进行缓存以存储get 查询的结果。
      • 有什么例子可以参考实现吗?
      • 您可以查看 redis 的官方文档。它很容易。也检查 Laravel Redis[laravel.com/docs/master/redis]。如果您觉得有困难,我会尝试写一篇关于此的文章。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-20
      • 1970-01-01
      • 1970-01-01
      • 2018-04-19
      • 1970-01-01
      相关资源
      最近更新 更多