作者:手浪用户2602933263 | 来源:互联网 | 2023-08-16 11:41
So I am having some trouble figuring out how to do a feed style mysql call, and I don't know if its an eloquent issue or a mysql issue. I am sure it is possible in both and I am just in need of some help.
因此,我在解决如何使用提要样式的mysql调用时遇到了一些麻烦,我不知道这是一个有说服力的问题还是一个mysql问题。我相信两者都有可能,我只是需要一些帮助。
So I have a user and they go to their feed page, on this page it shows stuff from their friends (friends votes, friends comments, friends status updates). So say I have tom, tim and taylor as my friends and I need to get all of their votes, comments, status updates. How do I go about this? I have a list of all the friends by Id number, and I have tables for each of the events (votes, comments, status updates) that have the Id stored in it to link back to the user. So how can I get all of that information at once so that I can display it in a feed in the form of.
我有一个用户,他们去他们的feed页面,在这个页面上显示他们的朋友的东西(朋友投票,朋友评论,朋友状态更新)。假设我有tom, tim和taylor作为我的朋友,我需要得到他们所有的选票,评论,状态更新。我该怎么做呢?我有一个按Id号排列的所有朋友的列表,我有每个事件(投票、评论、状态更新)的表,其中存储了Id以链接回用户。我如何能一次得到所有这些信息,这样我就可以在提要中以。
Tim commented "Cool"
提姆说“酷”
Taylor Said "Woot first status update~!"
泰勒说“Woot first status update~!”
Taylor Voted on "Best competition ever"
泰勒投票评选“史上最好的比赛”
Edit @damiani So after doing the model changes I have code like this, and it does return the correct rows
编辑@damiani,在做了模型修改之后,我有这样的代码,它确实返回了正确的行
$friends_votes = $user->friends()->join('votes', 'votes.userId', '=', 'friend.friendId')->orderBy('created_at', 'DESC')->get(['votes.*']);
$friends_comments = $user->friends()->join('comments', 'comments.userId', '=', 'friend.friendId')->orderBy('created_at', 'DESC')->get(['comments.*']);
$friends_status = $user->friends()->join('status', 'status.userId', '=', 'friend.friendId')->orderBy('created_at', 'DESC')->get(['status.*']);
But I would like them all to happen at once, this is because mysql sorting thousands of records in order is 100x faster then php taking 3 lists, merging them and then doing it. Any ideas?
但是我希望它们同时发生,这是因为mysql对成千上万条记录进行排序的速度比php快100倍,php取3个列表,合并它们,然后进行排序。什么好主意吗?
2 个解决方案
23
I'm sure there are other ways to accomplish this, but one solution would be to use join
through the Query Builder.
我确信还有其他方法可以实现这一点,但是一种解决方案是通过查询构建器使用join。
If you have tables set up something like this:
如果你有这样的表格:
users
id
...
friends
id
user_id
friend_id
...
votes, comments and status_updates (3 tables)
id
user_id
....
In your User model:
在你的用户模型:
class User extends Eloquent {
public function friends()
{
return $this->hasMany('Friend');
}
}
In your Friend model:
在你的朋友的模型:
class Friend extends Eloquent {
public function user()
{
return $this->belongsTo('User');
}
}
Then, to gather all the votes for the friends of the user with the id of 1, you could run this query:
然后,要为id为1的用户的朋友收集所有选票,可以运行以下查询:
$user = User::find(1);
$friends_votes = $user->friends()
->with('user') // bring along details of the friend
->join('votes', 'votes.user_id', '=', 'friends.friend_id')
->get(['votes.*']); // exclude extra details from friends table
Run the same join
for the comments
and status_updates
tables. If you would like votes, comments, and status_updates to be in one chronological list, you can merge the resulting three collections into one and then sort the merged collection.
对注释和status_updates表运行相同的连接。如果您希望在一个时间列表中使用投票、注释和status_updates,您可以将产生的三个集合合并为一个,然后对合并的集合进行排序。
Edit
编辑
To get votes, comments, and status updates in one query, you could build up each query and then union the results. Unfortunately, this doesn't seem to work if we use the Eloquent hasMany
relationship (see comments for this question for a discussion of that problem) so we have to modify to queries to use where
instead:
要在一个查询中获得选票、注释和状态更新,可以构建每个查询,然后将结果合并。不幸的是,如果我们使用雄辩的hasMany关系(关于这个问题的讨论请参阅对这个问题的评论),这似乎行不通,因此我们必须修改查询以使用where:
$friends_votes =
DB::table('friends')->where('friends.user_id','1')
->join('votes', 'votes.user_id', '=', 'friends.friend_id');
$friends_comments =
DB::table('friends')->where('friends.user_id','1')
->join('comments', 'comments.user_id', '=', 'friends.friend_id');
$friends_status_updates =
DB::table('status_updates')->where('status_updates.user_id','1')
->join('friends', 'status_updates.user_id', '=', 'friends.friend_id');
$friends_events =
$friends_votes
->union($friends_comments)
->union($friends_status_updates)
->get();
At this point, though, our query is getting a bit hairy, so a polymorphic relationship with and an extra table (like DefiniteIntegral suggests below) might be a better idea.
不过,在这一点上,我们的查询变得有点麻烦了,因此一个多态关系和一个额外的表(就像下面给出的定义一样)可能是个更好的主意。