制作智能通知列表


Making a smart notification list

场景

一个具有上传、评论、点赞、关注用户等基本功能的图片网站。

现在我有了一个基本的通知系统,我很快就建立了这个系统,基本上,当一个事件发生时,比如上传之类的,它就会被插入到notifications表中,然后有一个read列来确定用户是否看到了它,很简单。

当前的示例输出是这样的,

John Doe liked Picture of my cat.
Sarah Doe liked Picture of my cat.
Adam Doe liked Picture of my cat.
Sarah Doe liked Picture of my cat.
Henry Doe is now following you.

它基本上是按输入时间排序的。

现在我想要实现的是类似于以下的东西,

4 users liked Picture of my cat.
Henry Doe is now following you.

我正在努力将我的PHP知识概括在这一点上,我能想到的最好的方法就是做这样的事情。

$query = mysql_query("SELECT * FROM `notifications` WHERE `read` = '0' LIMIT 20");
$likes = array();
$following = array();
while($row = mysql_fetch_array($query)){
    if($row['type'] == "like"){
        array_push($likes,$row['id']);
    }   elseif($row['type'] == "following"){
        array_push($following,$row['id']);
    }
}

然后以某种方式对它们进行排序以正确显示。但这似乎仍然非常复杂。

还有一件事需要考虑,如果有人提出了一个建议,那么制定一个算法来对他们进行分组是不是一个好主意,即使他们不是直接在一起,例如相隔5分钟,但中间有不同的通知,例如

John Doe liked Picture of my cat.
John Doe is now following you.
Sarah Doe liked Picture of my cat.
Sarah is now following you.

进入

2 People liked Picture of my cat.
2 New Users are now following you.

我认为最好的解决方案是在SQL中使用GROUP BY,而不是在PHP侧。您需要按事件类型对结果进行分组。如果只有一个结果,只需使用第二个查询来显示单个结果。如果有多个结果,只需按预期显示COUNT(*)即可。

编辑:示例。

SELECT event_type, COUNT(*) AS count FROM `notifications` WHERE `read` = '0' GROUP BY event_type
result:
event_type  count
----------  -----
4           4
6           2
9           1
12          2

然后,您可以对只出现过一次的事件运行第二次查询。

SELECT * FROM `notifications` WHERE `read` = '0' AND `event_type` = '9'

当然,你也应该在结束时更改它们的读取状态

UPDATE `notifications` SET `read` = '1' WHERE `read` = '0'

这些只是快速准备的例子。您应该注意特殊情况,只更新显示的条目等。

我使用event_type作为字段。我相信你有这样的领域。您应该根据数据库结构重命名该部分。

以FB为例,无论计数多少,都会处理通知。如果我们点击FB上的点赞数量,我们会得到喜欢它的人的反馈,所以这个数字只是处理过的项目的一个占位符。

当你正在处理时,保持通知的计数

mysql_query("SELECT * FROM `notifications` WHERE `read` = '0' AND 'date_added' > {SOMETIMEEXPRESSION} GROUP BY type LIMIT 20");
while($row = mysql_fetch_array($query)) {
if ($curType != $row['type']) {
    $curType = $row['type'];
    $curCount = 0;
    //Other Type switch conditions
 }
//    do the magic that you wish to do for the type.
}