Laravel 使用预先加载和联合查询

Posted

技术标签:

【中文标题】Laravel 使用预先加载和联合查询【英文标题】:Laravel using eager loading with union queries 【发布时间】:2017-11-20 11:49:09 【问题描述】:

我正在使用联合来加入 2 个查询。在我的第一个查询中,我使用with eloquent 方法来急切地加载它的关系,然后在我的第二个查询中,我使用连接来组合 2。我尝试了许多不同的方法,但到目前为止都没有奏效。

如果我只查询$establishments,以下所有尝试都有效。 如果我进行独立查询,所有关系都会正常工作。

尝试 1

我只是添加了with 方法。在我的结果中,它没有显示任何结果,它完全忽略了它。

$establishemnts = Establishment::select('establishments.name', 'establishments.category_id',
        DB::raw("MATCH (establishments.name) AGAINST ('$text*' IN BOOLEAN MODE) as scores"),
        DB::raw("'establishment' as object_type")
    )
    ->with('category')
    ->whereRaw("MATCH (establishments.name) AGAINST ('$text*' IN BOOLEAN MODE)")
    ->where('status_id', Status::ACTIVE);

$query = Event::select('events.name', DB::raw('null as category_id'),
        DB::raw("MATCH (events.name) AGAINST ('$text*' IN BOOLEAN MODE) as scores"),
        DB::raw("'event' as object_type")
    )
    ->whereRaw("MATCH (events.name) AGAINST ('$text*' IN BOOLEAN MODE)")
    ->where('status_id', Status::ACTIVE)
    ->union($establishemnts)
    ->orderBy('scores', 'desc')
    ->limit(6)
    ->get();

结果


    "data": [
    
        "name": "Group",
        "category_id": null,
        "scores": 6.3736681938171,
        "object_type": "event"
    ,
 ...

尝试 2

与尝试 1 相同的查询,但添加了 ->union($establishemnts->getQuery()) 我在其他一些回复中看到了这一点。它也返回与 Attemp 1 相同的结果。

尝试 3

我认为由于第一个查询返回 5 个结果,第二个返回 4 个结果,这是不匹配的原因,也是事件未显示该列的原因。所以我添加了DB::raw('null as category_id') 作为另一列,所以它们的数量相同。那也没有用。它告诉我他们有不同数量的列。

尝试 4

我在第二个查询中添加了->with('promotions'),因此它们将具有相同的结构。

结果 4


"data": [
    
        "name": "Group",
        "category_id": null,
        "scores": 6.3736681938171,
        "object_type": "event",
        "promotions": []
    ,
....

对于所有结果,它给了我一个空的promotions,这是正确的,因为promotions 是空的。但它没有显示第一个查询的关系。这就像->with('promotions') 覆盖了它。

最后的尝试

我切换了查询。查询 1 变成了查询 2,并在第二个查询上进行了联接。这给我带来了正确的关系,但让我思考当我想为两个查询急切加载时会发生什么?似乎第二个急切加载器总是替换或第一个带有急切加载器的查询永远不会被执行。

【问题讨论】:

你在模型中建立了关系吗? @kerrin 是的,所有关系都是正确的,就像我在上面提到的那样,如果我独立进行查询,它们会给我带来正确的数据 遇到同样的问题,你找到解决办法了吗? 【参考方案1】:

假设一个机构可以有许多活动,并且一个活动可以在多个机构举行,则每个模型都需要设置为具有多对多关系。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Establishment extends Model

    /**
     * The events that belong to the establishment.
     */
    public function events()
    
        return $this->belongsToMany('App\Event');
    

反之:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Event extends Model

    /**
     * The establishments that belong to the event.
     */
    public function roles()
    
        return $this->belongsToMany('App\Establishment');
    

一旦定义了关系,您就可以使用with 方法进行预加载:

$establishments = Establishment::with('events')->get();

【讨论】:

感谢您的回复,但我的问题更多是针对在 2 个查询上使用 union 方法,同时在每个查询上使用预加载 它是一种搜索方法,我在其中搜索 2 个不同的表,因此不是先搜索一个表然后再搜索另一个,而是使用联合我可以使用一个查询 有什么关系?您有多对多的场所/活动 - 促销和分数如何适应?

以上是关于Laravel 使用预先加载和联合查询的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 查询生成器联合:添加“表名”列

在 Laravel Eloquent 中,你如何在联合范围之外进行两个联合查询和一个选择?

如何使用 laravel 查询生成器从表联合的结果中选择列?

sql查询到带有联合的laravel查询

Laravel 在联合结果中添加 where 子句

将原始联合查询转换为雄辩的关系