如何从每个父模型中获取 N 条记录?在 laravel 中雄辩
Posted
技术标签:
【中文标题】如何从每个父模型中获取 N 条记录?在 laravel 中雄辩【英文标题】:how to get N records from a model per parent ? In laravel eloquent 【发布时间】:2018-11-18 13:52:19 【问题描述】:如何在 laravel eloquent 中从每个父级的模型中获取 n 条记录。
例如,假设我有 products
表和 categories
表。我想要一个名称以A
开头的所有产品的列表,但每个category
不超过 10 个产品。
我的表结构是这样的。
产品表
---------------------------------
id | title | slug | category_id
----------------------------------
分类表
--------------
id | title |
--------------
我试图遵循这个例子,这正是我想要的 https://softonsofa.com/tweaking-eloquent-relations-how-to-get-n-related-models-per-parent/
但是当我在 product model
添加范围后尝试像链接中的示例一样查询时。它抛出和 sql 错误说。
SQLSTATE[HY000]:一般错误:1267 非法混合排序规则 (utf8mb4_unicode_ci,IMPLICIT) 和 (utf8mb4_0900_ai_ci,IMPLICIT) operation '=' (SQL: select count(*) as aggregate from...
谁能告诉我如何获得每个相关模型的 n 个结果或如何修复此错误。
【问题讨论】:
什么 mysql 版本?因为 MySQL 8.0 有比使用 MySQL 的用户变量更好的方法。 @RaymondNijland 我正在开发最新的 Xamp 服务器。在 phpmyadmin 中显示服务器版本:10.1.25-MariaDB。我猜那个 基本上,错误已经在告诉您该怎么做:检查表的排序规则。如果您故意将它们设置为不同的类型,那么您会很倒霉,因为那样这些类型的查询将不起作用。如果不是这种情况,请确保所有表和列的排序规则都相同。有很多资源可以解释如何去做。 @Namoshek,可能是因为我的类别位于 mariadb 的 xamp 服务器上,而我的产品位于 inodb 中的实时服务器上,这可能是导致问题的原因吗?如果是这样,你能告诉我如何解决这个问题吗?谢谢 不知道,说实话。对不起。 【参考方案1】:Laravel 对此没有原生支持。
我为它创建了一个包:https://github.com/staudenmeir/eloquent-eager-limit
在父模型和相关模型中使用 HasEagerLimit
特征。
class Category extends Model
use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
class Product extends Model
use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
然后您可以将limit()
/take()
应用于您的关系:
Category::with(['products' => function($query)
$query->where('name', 'LIKE', 'A%')->limit(10);
])->get();
【讨论】:
【参考方案2】:调用关系时传递查询:
Category::with(['products' => function($query)
$query->take(10)->skip(0);
])->get();
假设您的 Category 模型中有一个关系。
public function products()...
【讨论】:
这将为您获取的所有类别总共加载10
产品。这意味着您最终可能会发现某些类别加载了零个产品,而其他类别加载了多个产品。
可以这样做,但我不想这样做有几个原因,其中之一是我无法对产品价格进行排序,并且应用与产品直接相关的其他过滤器会有点困难
为什么不呢? $query->where('price', '>', 0)->take(10)->skip(0);你可以在'with'关系中使用几个雄辩的函数......在'with'之前你也可以使用'has'。这么多选择。干净简单。
在这一切之后,您仍然可以过滤收藏。【参考方案3】:
在我看来,对于每个 categoryID,您需要列出一个包含 10 个产品的数组。使用 Eloquent,这就是我想出的
$categories = Category::all()
productsArray = array();
foreach($categories as $category)
$products = Product::where('category_id', $category->id)->where('title', 'LIKE', 'A%')->get();
if(sizeof($products))
$products = $products->take(10);
$productsArray[$category->id] = $products;
return $productsArray;
我看到的唯一缺点是每个类别 ID 的循环,如果您有数千条记录,这可能需要更多时间。如果你想在你的刀片文件中显示它,你可以有任何其他的键,除了 $category->id。
【讨论】:
口才的效率在哪里?【参考方案4】:首先让我们创建模型:
class Category extends Model
public $timestamps = false;
protected $fillable = [
'title'];
public function products()
return $this->hasMany(\App\Products::class)->limit(10);
第二个:
class Products extends Model
public $timestamps = false;
protected $casts = [
'category_id' => 'int',
];
protected $fillable = [
'title',
'slug'
];
public function category()
return $this->belongsTo(\App\Category::class);
使用 eloquent 如下:
$Category = Category::get();
也可以使用starts_with()
来定义列、字
【讨论】:
嗨,这可能是根据类别过滤选择产品的正确方法。但我想要的是其他方式,即基于类别的产品,以便我可以轻松地对产品应用过滤器。此外,我在每个表中都有超过 250 万条记录,这样会占用大量时间和服务器资源。但你的答案很棒:)) 实际上这是基于类别的产品,使用 foreach 您只需执行$Category->product->name
并且您已经获得了所有类别,每个类别都有 10 个产品,如果您想应用过滤器,您只需应用 $Category->products->where()->otherfilters()->get();
就可以了.如果我的回答对您有帮助,请不要忘记将其标记为 :)以上是关于如何从每个父模型中获取 N 条记录?在 laravel 中雄辩的主要内容,如果未能解决你的问题,请参考以下文章