如何在laravel eloquent查询中获得前10个类别列表

时间:2018-03-04 05:28:31

标签: laravel laravel-5 eloquent laravel-5.3

我有三个表一个是category表,另一个是product表和另外一个product_to_category表,它只有product_idcategory_id

现在,我希望获得最多10个类别,产品数量最多,每个类别包含10个产品的详细信息。

我写的是

$result = ProductToCategory::groupBy('category_id')->with(['product',function($q){
  $q->take(10);
}])->orderBy('category_id)->take(10);

但这不起作用。如何正确编写此查询 谁能请帮忙。 TY

模型关系

对于产品型号

public function category(){
        return $this->belongsTo(ProductToCategory::class);
    }

对于类别模型

 public function products()
    {
        return $this->hasMany(ProductToCategory::class);
    }

对于ProductToCategory模型

 public function product()
    {
        return $this->hasMany(Product::class);
    }

    public function category()
    {
        return $this->belongsTo(Category::class);
    }

2 个答案:

答案 0 :(得分:3)

最有效的方法是使用原始SQL查询,因为您无法使用预先加载约束来过滤产品。

但是如果你想要一个Eloquent解决方案,请定义关系:

Product模型中:

public function categories()
{
    return $this->belongsToMany(Category::class, 'product_to_category');
}

Category模型中:

public function products()
{
    return $this->belongsToMany(Product::class, 'product_to_category');
}

然后你将有两个选择,两者都有其优点和缺点:

1。此代码仅执行2次查询,但会占用更多内存。您可以使用他们的产品获得前十个类别:

$categories = Category::withCount('products')->latest('products_count')->take(10)->with('products')->get();

然后只保留前十种产品:

$categories->transform(function($category) {
    $topProducts = $category->products->take(10);
    unset($category->products);
    $category->products = $topProducts;
    return $category;
});

2. 此解决方案将创建12个查询,但会保存内存:

$categories = Category::withCount('products')->latest('products_count')->take(10)->get();
$categories->transform(function($category) {
    $category->products = Product::whereHas('categories', function($q) use($category) {
        $q->where('id', $category->id);
    })
    ->take(10)
    ->get();
    return $category;
});

答案 1 :(得分:2)

这是DB facade版本:

$tenPopularTags = DB::table('product_to_category')
                      ->join('category', 'product_to_category.category_id', '=', 'category.id')
                     ->select(DB::raw('count(product_to_category.category_id) as repetition, question_tag.tag_id'))
                     ->groupBy('product_to_category.category_id')
                     ->orderBy('repetition', 'desc')->take(10)
                     ->get();

但是我喜欢@Alexey Mezenin这样做的方式。因为这是更清洁的方式已经定制了一点:

$tenCategories = Category::withCount('products')->orderBy('questions_count', 'DESC')->take(10)->get();

在我的项目博客中使用过帖子和类别关系,它都有效!