Hi everybody I have 3 table:
a table called content with the below attributes:
id
name
table_type_id
release_date
popularity
another table called content_genres with the below attributes:
content_id
genres_id
another table called genres with the below attributes:
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
in postgresql this would be easy:
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
but when I try to write this same query in eloquent I have some problems:
query 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:
$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:
18950
number of results from query2:
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?
The last thing is the big problem which I have had all the week.
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.
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.
You should merge both queries. I see two ways of doing this.
1) Join content_genres
twice:
$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()
:
$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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.