简体   繁体   English

使用Laravel Eloquent处理对话

[英]Handling conversations using Laravel Eloquent

I've got no where to turn. 我没有路可走。 I'm hoping someone here will point me in the right direction. 我希望这里有人会指出正确的方向。

Every User has a Statistics row which contains their friend count, friend request count, new message count and message count. 每个用户都有一个统计行,其中包含他们的朋友计数,朋友请求计数,新消息计数和消息计数。 It is far quicker to select 1 row from this table as opposed to performing a large query full of joins etc just to retrieve a users statistics on every page load. 从表中选择1行比执行仅对连接等进行大型查询只是为了在每次页面加载时检索用户统计信息要快得多。

The problem here is that, that row needs to be updated on every new conversation message. 这里的问题是,该行需要在每条新的对话消息上进行更新。 This isn't really a concern if I'm just updating one row. 如果我仅更新一行,那么这并不是真正的问题。 A conversation could have multiple participants (let's take 20 for example). 一个对话可以有多个参与者(例如,以20个为例)。

I will need to update 20 rows in the statistics table. 我将需要更新统计信息表中的20行。 This is considered a bad idea as it will cause blocking for other users making a request. 这被认为是一个坏主意,因为它会阻止其他用户发出请求。 Understandable. 可以理解的。 I will need to update 20 rows in the conversation participants table (has_read flag, has_deleted flag and possibly created_at as the participant is "re-instated" to the conversation). 我将需要更新会话参与者表中的20行(has_read标志,has_deleted标志以及可能创建了“参与者”,因为参与者已“恢复”到会话)。 Ok so in total I'm updating 40 rows on every new message... sounds a bit overkill but it doesn't stop there. 好的,总的来说,我将在每条新消息上更新40行...听起来有些过分了,但还不止于此。

Updating rows in eloquent is not simple. 雄辩地更新行并不简单。 I don't know how you can do a bulk update in eloquent either so the code ends up like this: 我也不知道您如何雄辩地进行批量更新,因此代码最终如下所示:

foreach ($conversation->participants as $participant) {
    if ($participant->user_id == Auth::user()->id) {
        continue;
    }

    $participant->has_read = 0;

    if ($participant->has_deleted == 1) {
        $participant->has_deleted = 0;
        $participant->created_at = DB::Raw('NOW()');
    }

    $participant->save();
    $participant->user->stats->new_messages += 1;
    $participant->user->stats->save();
}

So already, I'm performing at least 40 queries. 因此,已经执行了至少40个查询。 Not to mention the user itself is not eager loaded... not really sure how to eager load them in relationships so I'm performing at least 60 queries by doing it in eloquent every time a new message is sent. 更不用说用户本身并不渴望加载...不十分确定如何渴望在关系中加载它们,因此我每次发送新消息时都会雄辩地执行至少60条查询。 I don't know about you, but to me that is cringe. 我不了解你,但是对我来说,这是种畏缩。

So basically, I'm unsure how to handle the whole statistics side of things and bulk updating. 因此,基本上,我不确定如何处理整个统计方面的内容和批量更新。 I feel as if I'm hit a brick wall and I'm not sure what to do or where to turn. 我感觉好像撞到了砖墙,不知道该做什么或该去哪里。 Please help, thanks. 请帮忙,谢谢。

Generally this is what is done for mass assignment: 通常,这是批量分配要做的事情:

1) Iterate over all the data and form an array of all the things that you need to update 1)遍历所有数据并形成需要更新的所有事物的数组

2) While iterating, form another array of id's of the rows to be updated. 2)在迭代时,形成要更新的行的ID的另一个数组。

3) With these two arrays, do mass assignment using WhereIn and update of eloquent. 3)使用这两个数组,使用WhereIn进行质量分配并更新雄辩。

Something like this: 像这样:

ParticipantModel::whereIn('id',$array_of_id)->update($data_to_update);

Your $data_to_update array should only contain the fields that are present in your table. $ data_to_update数组应仅包含表中存在的字段。

Simplifying your example, for the sake of explanation this is how you can do the above steps: 简化示例,为便于说明,这是执行上述步骤的方法:

$array_of_id = array();
$data_to_update = array();

foreach ($conversation->participants as $participant) {
    $array_od_id[] = $participant['id'] //Pushing the ids into the array
    $participant['has_read'] = 0;
    if ($participant['has_deleted'] == 1) {
        $participant['has_deleted'] = 0;
        $participant['created_at'] = DB::Raw('NOW()');
    }
    $data_to_update[] = $participant; //Pushing each participant into data_to_update
}

/* You can either use DB raw or model,if you have it */
ParticipantModel::whereIn('id',$array_of_id)->update($data_to_update);

The advantage is that now you are making only one DB query to update the data, instead of making update query for each record. 好处是现在您只需要执行一个数据库查询来更新数据,而不是对每个记录进行更新查询。

Please note that I have simplified your example. 请注意,我已经简化了您的示例。 You have to figure out how you can extend this logic to accommodate your user table updates. 您必须弄清楚如何扩展此逻辑以适应用户表更新。

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

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