【问题标题】:Eloquent ORM Eager-loading Distinct Records in Many to Many RelationshipEloquent ORM Eager-loading 多对多关系中的不同记录
【发布时间】:2013-08-23 12:39:55
【问题描述】:

背景

我有一个列表模型,它属于并有很多订阅者。当然还有一个订阅者,它属于并拥有许多列表。

问题

我想从多个列表中快速加载所有订阅者。但是,我只对不同的订阅者感兴趣,因为订阅者可以拥有并且确实属于多个列表。

我的尝试

我使用了distinct() 方法,但这并没有带来任何乐趣。而且我还可以循环遍历结果集以手动切出重复项。只是想知道是否有办法让 Laravel 为我完成这项肮脏的工作?

代码

    $lists = Input::get('listsarray');

    $addresses = Addressbook::with(array('subscribers' => function($query)
                    {
                        $query->where('active', '=', 1);
                        // $query->distinct(); //This didn't work
                    }))->whereIn('id', $lists)->get();

【问题讨论】:

    标签: laravel laravel-4 eloquent


    【解决方案1】:

    通过加入检索唯一订阅者

    我会尽量使用Lists 而不是Adressbook 来解释它,因为我无法真正理解您的模型,这可能会引起进一步的混乱。

    如果我正确理解了您的 cmets,您正在尝试检索与 id IN listarray 列表关联的所有唯一订阅者。在这种情况下,Eager Loading 不是正确的方法。急切加载的目的是为模型预加载关联,以便以后使用它们。在您的情况下,您检索的不是Lists 和他们的Subscribers,而是唯一的Subscribers 本身。

    $lists = Input::get('listsarray');
    
    $subscribers = Subscriber::join('list_subscriber', 'list_subscriber.subscriber_id', '=', 'subscribers.id')
        ->whereIn('list_subscriber.list_id', $lists)
        ->groupBy('list_subscriber.subscriber_id')
        ->get(array('subscribers.*'));
    

    如果您还希望检索与此类订阅者关联的所有列表,您可以这样做:

    // Simply include a with('lists') and Eloquent will eager load them
    $subscribers = Subscriber::with('lists')
        ->join('list_subscriber', 'list_subscriber.subscriber_id', '=', 'subscribers.id')
        ->whereIn('list_subscriber.list_id', $lists)
        ->groupBy('list_subscriber.subscriber_id')
        ->get(array('subscribers.*'));
    

    急切加载

    如果只是为了提高性能,你不需要使用 distinct,Laravel 已经做到了。 Eloquent 的行为如下:

    1. 获取所有lists
    2. 遍历lists 构建唯一list_ids 的数组
    3. 使用WHERE list_id IN (X, Y, Z)获取所有list_subscribers
    4. 遍历所有list_subscribers 构建唯一subscriber_id 的数组
    5. 使用WHERE id IN (X, Y, Z)获取所有subscribers

    【讨论】:

    • 不幸的是,它似乎对我不起作用。例如,当我遍历地址,然后遍历他们的订阅者和 var_dump() 订阅者 ID 时,我得到 4、6、7、11、12、7、12。还有一些是重复的。我是否以错误的方式提取这些内容?
    • 嗯,我实际上理解您正在尝试提高 SQL 查询性能。如果是这样,Eloquent 已经为您做到了。你能解释一下你到底想达到什么目标吗?我无法真正理解真正的问题(非技术问题)以提供更准确的答案。
    • 我想你理解了这个问题。只是答案对我不起作用。我有一个列表 ID 数组。我想获取属于这些列表的所有订阅者。而且我不想要重复的订阅者。因此,如果某人属于两个或多个列表,那么他们应该只在结果集中出现一次。
    • 谢谢!刚刚做了两次修改,效果很好!数据透视表是“list_subscriber”(遵循文档中的约定),最后的“get”需要一个数组。因此,我将其修改为 ->get(array('subscribers.*'));和嘘!谢谢,伙计。
    • 你是完全正确的(我已经习惯了 Laravel 3,以至于这些往往会通过)。我会在答案上解决这些问题:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 2021-10-17
    • 2017-06-28
    • 1970-01-01
    相关资源
    最近更新 更多