如何在 Laravel 中明智地获取产品类别?
Posted
技术标签:
【中文标题】如何在 Laravel 中明智地获取产品类别?【英文标题】:How to get products category wise in Laravel? 【发布时间】:2021-10-08 13:32:15 【问题描述】:here 提出了类似的问题。
我正在研究 API。我的产品表包含一万多个不同类别的产品。我需要减少查询执行时间,因此为此,我必须修改一个 API,该 API 将仅获取每个类别的 20 个产品,并将整个 API 响应按类别分组。 API 响应如下所示。
"data":
"products":
"Beauticians & Style": [
"Title": "Product A",
"Price": "0.00",
"DiscountPrice": 0
,
"Title": "Product B",
"Price": "0.00",
"DiscountPrice": 0
],
"Groceries": [
"Title": "Product G",
"Price": "0.00",
"DiscountPrice": 0
,
"Title": "Product R",
"Price": "0.00",
"DiscountPrice": 0
,
"Title": "Product O",
"Price": "0.00",
"DiscountPrice": 0
,
"Title": "Product C",
"Price": "0.00",
"DiscountPrice": 0
],
"Women's Fashion": [
"Title": "Product W",
"Price": "0.00",
"DiscountPrice": 0
,
"Title": "Product O",
"Price": "0.00",
"DiscountPrice": 0
,
"Title": "Product M",
"Price": "0.00",
"DiscountPrice": 0
]
控制器
$products = Category::with('products', function($q)
$q->take(20);
)->get();
类别模型
class Category extends Model
use HasFactory;
public function products()
return $this->hasMany('App\Models\Product', 'CategoryID', 'CategoryID');
我试过了,但没有得到确切的结果。
【问题讨论】:
【参考方案1】:当访问 Eloquent 关系作为属性时,相关模型是“延迟加载”。 这意味着在您第一次访问该属性之前不会实际加载关系数据。
解决方法,你可以使用:
$products = Category::with('products')
->get()
->map(function ($query)
$query->setRelation('products', $query->products->take(20));
return $query;
);
参考:
"This is not a bug, it's a limitation"更新
OP 评论:
但在这种情况下,我们获取所有 10k 个产品,然后在集合上设置关系
是的,这是性能问题,但是,您的问题是关于 eadger。 This is limitation。
Eloquent 作为工具,而不是解决方案。它只是 SQL 的一个包装器。如果您想将每个类别的产品数量限制为(n)
,则查询会变得复杂。
要解决此问题,您需要使用window function:
SELECT *
FROM (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY `category_id`) AS row_num
FROM `products`
) AS temp_table
WHERE row_num <= 10
ORDER BY row_num
或者,您可以使用this Laravel Eloquent extension 来允许使用窗口函数限制每个父级的急切加载结果的数量。
类别模型
use Staudenmeir\EloquentEagerLimit\HasEagerLimit;
use App\Models\Product;
class Category extends Model
use HasEagerLimit;
public function products()
return $this->hasMany(Product::class);
产品型号
use Staudenmeir\EloquentEagerLimit\HasEagerLimit;
class Product extends Model
use HasEagerLimit;
试试
$products = Category::with(['products' => function ($query)
$query->latest()->limit(20);
])->get();
这对你解释够了吗?
【讨论】:
但在这种情况下,我们正在获取所有 10k 产品,然后在集合上设置关系。【参考方案2】:如果每个产品只有一个类别,您的表格结构必须如下:
products
id
...
category_id
categories
id
...
并且您在 Category 中的产品关系必须如下:
class Category extends Model
use HasFactory;
public function products()
return $this->hasMany(App\Models\Product::class);
并将您的控制器更改为:
$products = Category::with('products', function($q)
$q->take(20);
)->get();
【讨论】:
以上是关于如何在 Laravel 中明智地获取产品类别?的主要内容,如果未能解决你的问题,请参考以下文章
如何在类别中创建 UITableViewCell 明智地排列 JSON 对象