Eloquent ORM 中的交集和分页

intersection and pagination in Eloquent ORM

大家好我有3个table:

a table 调用了 content,具有以下属性:

id
name
table_type_id
release_date
popularity

另一个名为 content_genres 的 table 具有以下属性:

content_id
genres_id

另一个 table 称为 流派 具有以下属性:

id
name

每个内容可以有多个流派,一个流派可以有多个内容。(多对多


好的,直到这里是不同 tables 的定义,现在我正在尝试进行查询以搜索具有例如 genre_id= 的内容1 同时 genre_id=2

postgresql 这很容易:

 SELECT content.id
 FROM content INNER JOIN content_genres ON content.id =content_genres.content_id
 WHERE content_genres.`genres_id`= 1

 INTERSECT

 SELECT content.id
 FROM content INNER JOIN content_genres ON content.id =content_genres.content_id
 WHERE content_genres.`genres_id`= 2
 ;

我做了一个查询,我做了另一个查询,然后我做了一个交集,得到具有 genre_id 1 和 2

的内容

但是当我尝试在 eloquent 中编写相同的查询时,我遇到了一些问题:

查询 1:

$content1=$this->content::join('content_genres','content_genres.content_id','=','content.id')
        ->with('genres')
        ->where('content_genres.genres_id',1)
        ->where('content.table_type_id',1)
        //->whereYear('release_date',2017)
        ->select('content.id','content.name','content.popularity')
        ->orderBy('popularity','desc')->get();

查询2:

$content2=$this->content::join('content_genres','content_genres.content_id','=','content.id')
        ->with('genres')
        ->where('content_genres.genres_id',2)
        ->where('content.table_type_id',1)
        //->whereYear('release_date',2017)
        ->select('content.id','content.name','content.popularity')
        ->orderBy('popularity','desc')->get();

路口:

 $final_result=$content1->intersect($content2);

好的,我们如何通过这种方式看到我们能够形成交叉路口,但我遇到了一些问题:

当我想做一个手动分页时,我不知道如何计算将要有交集的元素,然后限制结果路口.

示例:

query1 的结果数:

18950

query2 的结果数:

22650

交集的结果数

3457

这很慢,因为我不能说限制查询 1 到 100 个结果,限制查询 2 到 100 个结果然后进行交集,我不能这样做,因为交集的结果数是不会总是一样的,所以出于这个原因 我如何在不加载 query1 和 query2 的所有结果的情况下对交叉点进行手动分页,说我想对 20 个结果的页面中的交叉点进行分页?

最后一件事是我整个星期都遇到的大问题。


real example

您转到此页面,然后在年份中输入 none,在流派中输入 select 两个随机流派。你怎么能看到那个路口的分页总是 20,不取决于路口是否有更多结果,总是 20。而且我很确定他们没有从数据库加载所有结果。


好成绩:

感谢回答,正确的方法如下:

 $this->content::join('content_genres as g1','g1.content_id','=','content.id')
->join('content_genres as g2','g2.content_id','=','content.id')
->where('g1.genres_id', 1)
->where('g2.genres_id', 2)

它对我有用,我可以选择其他选项,但我有一个多对多的关系,因为我的 content_genres 是一个支点 table,但我认为我也会有效。

您应该合并这两个查询。我看到有两种方法可以做到这一点。

1) 加入content_genres两次:

$this->content::join('content_genres as g1','g1.content_id','=','content.id')
    ->join('content_genres as g2','g2.content_id','=','content.id')
    ->where('g1.genres_id', 1)
    ->where('g2.genres_id', 2)

2) 使用whereHas():

$this->content::whereHas('content_genres', function($query) {
    $query->where('genres_id', 1)
})->whereHas('content_genres', function($query) {
    $query->where('genres_id', 2)
})

这里需要关系:内容→HasMany→content_genres