简体   繁体   English

口才ORM中的相交和分页

[英]intersection and pagination in Eloquent ORM

Hi everybody I have 3 table: 大家好,我有3张桌子:

a table called content with the below attributes: 具有以下属性的名为content的表:

id
name
table_type_id
release_date
popularity

another table called content_genres with the below attributes: 另一个名为content_genres的表,具有以下属性:

content_id
genres_id

another table called genres with the below attributes: 另一个具有以下属性的表,称为genres

id
name

each content can have multiple genres, and a genre can have multiple content.( many to many ) 每个内容可以具有多种类型,一种类型可以具有多种内容。( 多对多


okay, until here is the definition of the different tables, now i am trying to make a query to search the content that has for example the genre_id=1 and at the same time the genre_id=2 好的,直到这里是不同表的定义,现在我正在尝试进行查询以搜索具有genre_id = 1和同时genre_id = 2的内容

in postgresql this would be easy: 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
 ;

I make one query, I make another query and then I make an intersection getting that content that has the genre_id 1 and 2 我进行一个查询,再进行另一个查询,然后进行交集以获取具有genre_id 1和2的内容


but when I try to write this same query in eloquent I have some problems: 但是当我试图雄辩地编写相同的查询时,我遇到了一些问题:

query 1: 查询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();

query 2: 查询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();

intersection: 路口:

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

okay how we have seen at this way we are able to make a intersection but I have some problems: 好的,我们以这种方式看到的图像能够交叉,但我有一些问题:

when I want to do a manual pagination I don't know how can I count the elements that is going to have the intersection, and after that limit the results of the intersection. 当我想进行手动分页时,我不知道如何计算将要有交点的元素,然后限制交点的结果。

example: 例:

number of results from query1: 查询1的结果数:

18950

number of results from query2: 查询2的结果数:

22650

number of results from intersection 相交的结果数

3457

this is very slow, because I can not say limit the query 1 to 100 results, limit the query 2 to 100 results and then make the intersection, I can not do this because the number of results from the intersection is not going to be always the same so for that reason how can I make a manual pagination over the intersection without load all the results from query1 and query2, saying I want to paginate the intersections in pages from 20 results? 这非常慢,因为我不能说将查询1限制为100个结果,将查询2限制为100个结果,然后进行相交,所以我不能这样做,因为相交的结果数不会总是相同,因此出于这个原因,我如何在不加载query1和query2的所有结果的情况下,对交点进行手动分页,说我想对20个结果中的交点进行分页?

The last thing is the big problem which I have had all the week. 最后一件事是我整周都遇到的大问题。


real example 真实的例子

you go to this page, then in year put none, and in genres select two random genres. 您转到此页面,然后在年份中不输入任何内容,在类型中选择两个随机类型。 how you can see the pagination of that intersection is always 20, doesn't depends if there is more results in the intersection or there isn't, always is 20. And I am pretty sure that they haven't load from the db all the results. 您如何看到该交叉点的分页始终为20,这并不取决于交叉点是否有更多结果,或者始终没有,这始终是20。而且我很确定它们没有从db中全部加载结果。


Good result: 好结果:

Thanks to the answer the correct way to do this is the below: 多亏了答案,正确的方法如下:

 $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)

it works for me, I could have chosen the other option but I have a many to many relation , because my content_genres is a pivot table, but I think that I would be also valid. 它对我有用,我可以选择其他选项,但是我有很多对很多的关系,因为我的content_genres是数据透视表,但是我认为我也是有效的。

You should merge both queries. 您应该合并两个查询。 I see two ways of doing this. 我看到了两种方法。

1) Join content_genres twice: 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) Use whereHas() : 2)使用whereHas()

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

This requires a relationship: content → HasMany → content_genres 这需要一个关系:content→ HasMany →content_genres

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM