0

0

Laravel 数据库通知聚合与计数更新策略

聖光之護

聖光之護

发布时间:2025-11-24 12:44:13

|

986人浏览过

|

来源于php中文网

原创

laravel 数据库通知聚合与计数更新策略

本文旨在提供一种优化 Laravel 数据库通知的方法,以避免在短时间内发送大量重复或相似的通知。通过实现基于时间窗口的通知聚合策略,可以在特定时间段内将多个相关事件合并为一个通知,并自动更新其计数,从而提升用户体验并减少数据库负担。

在构建现代 Web 应用程序时,通知功能是用户体验的关键组成部分。然而,当系统在短时间内触发大量相似的通知时(例如,多个新帖子匹配了用户的保存搜索),用户可能会感到信息过载。为了解决这一问题,我们可以采用一种策略:在指定的时间窗口内,将相关的通知进行聚合,而不是为每个事件都创建一条新的通知。这种聚合方式通常表现为更新现有通知的计数和内容。

核心策略:基于时间窗口的通知聚合

该策略的核心思想是:当一个新事件触发通知时,首先检查在最近一个预定义的时间窗口内(例如30分钟),是否存在与此事件高度相关的未读通知。

  1. 如果存在:更新该现有通知的计数和内容,并阻止系统创建新的通知记录。
  2. 如果不存在:则创建一个全新的通知。

通过这种方式,用户只会看到一条不断更新的通知,而不是一连串独立的通知,直到超过时间窗口或用户阅读了该通知。

科海网络企业网站管理系统2011.5.17
科海网络企业网站管理系统2011.5.17

科海网络企业网站管理系统支持ASP+ACCESS数据库的虚拟主机即可,上传至服务器上,请把lxlweb文件夹放在网站根目录。 前台功能介绍:企业网站通用七大栏目 网站首页:综合性的显示网站相关信息;公司简介:显示与公司相关内容:公司简介、企业文化、发展策略、人才政策、联系方式等,栏目可以后台无限添加;新闻中心:按新闻类别显示新闻信息、新闻搜索功能,新闻分类后台可无限添加;产品展示:按产品分类显示

下载

实现方法:修改 toDatabase 方法

Laravel 的通知系统通过 toDatabase 方法定义了通知如何存储到数据库。为了实现通知聚合,我们需要在该方法中加入条件逻辑。关键在于,当成功更新现有通知时,toDatabase 方法应返回 null 或 false,以阻止 Laravel 默认的通知创建行为。

以下是修改后的 toDatabase 方法示例,它实现了基于搜索 ID 和时间窗口的通知聚合:

search = $search;
        $this->post = $post;
    }

    /**
     * 获取通知的投递渠道。
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable): array
    {
        return ['database'];
    }

    /**
     * 获取通知的数据库表示。
     *
     * @param  mixed  $notifiable
     * @return array|null
     */
    public function toDatabase($notifiable): ?array
    {
        // 定义通知聚合的时间窗口(例如30分钟)
        $timeWindowMinutes = 30;

        // 构造当前通知的数据,其中包含用于识别聚合的键(如 'search_id')
        $currentNotificationData = [
            'search_id' => $this->search->id,
            'title' => $this->search->title,
            'parameters' => $this->search->parameters,
            // 如果需要,可以在这里记录触发当前通知的最新帖子ID
            'latest_post_id' => $this->post ? $this->post->id : null, 
        ];

        // 尝试查找在指定时间窗口内,与当前搜索相关的未读通知
        // 1. where('type', self::class) 确保只聚合同类型的通知
        // 2. where('read_at', null) 确保只聚合用户尚未阅读的通知
        // 3. where('data->search_id', $this->search->id) 通过JSON字段精确匹配搜索ID
        // 4. where('created_at', '>=', now()->subMinutes($timeWindowMinutes)) 定义时间窗口
        $existingNotification = $notifiable->notifications()
            ->where('type', self::class)
            ->where('read_at', null) 
            ->where('data->search_id', $this->search->id) 
            ->where('created_at', '>=', now()->subMinutes($timeWindowMinutes))
            ->first();

        if ($existingNotification) {
            // 如果找到现有通知,更新其计数和内容
            $currentCount = $existingNotification->data['count'] ?? 1;
            $newCount = $currentCount + 1;

            // 更新现有通知的数据
            $existingNotification->update([
                'data' => array_merge($existingNotification->data, [
                    'count' => $newCount,
                    'content' => [
                        'en' => "{$newCount} new posts matched with your saved search {$this->search->title} have been posted. Click here to view more.",
                        // 可以添加一个时间戳,表示最后更新时间
                        'last_updated' => now()->toDateTimeString(),
                    ],
                    // 更新最新的帖子ID
                    'latest_post_id' => $this->post ? $this->post->id : null,
                ]),
                'updated_at' => now(), // 手动更新 updated_at 字段
            ]);

            // 返回 null 阻止创建新的通知记录
            return null;
        }

        // 如果没有找到现有通知,则创建新的通知
        return [
            'content' => [
                'en' => "1 new post matched with your saved search {$this->search->title} has been posted. Click here to view more.",
            ],
            'count' => 1,
            // 确保这里返回的数据结构与查询时使用的键(如 'search_id')一致
            'search_id' => $this->search->id, 
            'parameters' => $this->search->parameters,
            'latest_post_id' => $this->post ? $this->post->id : null,
        ];
    }
}

注意事项

  1. return null 的关键作用:当 toDatabase 方法返回 null 或 false 时,Laravel 的通知系统将不会在 notifications 表中创建新的记录。这是实现通知聚合而不创建新通知的核心机制。
  2. 通知类型过滤 (where('type', self::class)):在查询现有通知时,务必通过 where('type', self::class) 过滤通知类型。这确保了我们只聚合相同类型的通知,避免将不同目的的通知混淆。
  3. read_at 状态过滤 (where('read_at', null)):通常情况下,我们只希望聚合用户尚未阅读的通知。一旦用户阅读了通知,即使在时间窗口内,也应该创建一个新的通知,以确保用户不会错过新的信息。
  4. 数据结构设计与查询
    • 在 toDatabase 返回的数组中,应包含一个或多个用于唯一标识聚合通知的键(例如 search_id)。
    • 查询现有通知时,使用 where('data->your_key', $value) 来精确匹配 JSON 字段中的特定键值。确保存储的键名和查询的键名一致。
  5. 手动更新 updated_at:当通过 update() 方法修改现有通知记录时,Laravel 默认不会自动更新 updated_at 字段(因为 MorphMany 关系通常不直接触发模型事件)。因此,建议手动将 updated_at 设置为 now(),以反映通知的实际更新时间。
  6. 内容动态更新:确保通知内容(如 content 字段)能够动态反映最新的计数和状态。在示例中,我们将计数直接嵌入到通知文本中。
  7. 队列处理 (ShouldQueue):对于可能涉及数据库查询和更新的通知逻辑,强烈建议实现 ShouldQueue 接口,将通知的发送和处理推送到队列中,以避免阻塞用户请求。
  8. 聚合粒度:根据业务需求,聚合的粒度可以更细致。例如,除了 search_id,还可以考虑用户的其他偏好设置或更复杂的事件关联规则。

总结

通过在 toDatabase 方法中引入条件逻辑并巧妙利用 return null,我们能够有效地实现 Laravel 数据库通知的聚合与计数更新。这种策略不仅减少了通知的泛滥,提升了用户体验,也降低了数据库的存储压力。在设计通知系统时,灵活运用这种模式,可以根据实际业务场景创建更加智能和用户友好的通知机制。

相关专题

更多
laravel组件介绍
laravel组件介绍

laravel 提供了丰富的组件,包括身份验证、模板引擎、缓存、命令行工具、数据库交互、对象关系映射器、事件处理、文件操作、电子邮件发送、队列管理和数据验证。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

319

2024.04.09

laravel中间件介绍
laravel中间件介绍

laravel 中间件分为五种类型:全局、路由、组、终止和自定。想了解更多laravel中间件的相关内容,可以阅读本专题下面的文章。

276

2024.04.09

laravel使用的设计模式有哪些
laravel使用的设计模式有哪些

laravel使用的设计模式有:1、单例模式;2、工厂方法模式;3、建造者模式;4、适配器模式;5、装饰器模式;6、策略模式;7、观察者模式。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

370

2024.04.09

thinkphp和laravel哪个简单
thinkphp和laravel哪个简单

对于初学者来说,laravel 的入门门槛较低,更易上手,原因包括:1. 更简单的安装和配置;2. 丰富的文档和社区支持;3. 简洁易懂的语法和 api;4. 平缓的学习曲线。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

371

2024.04.10

laravel入门教程
laravel入门教程

本专题整合了laravel入门教程,想了解更多详细内容,请阅读专题下面的文章。

81

2025.08.05

laravel实战教程
laravel实战教程

本专题整合了laravel实战教程,阅读专题下面的文章了解更多详细内容。

64

2025.08.05

laravel面试题
laravel面试题

本专题整合了laravel面试题相关内容,阅读专题下面的文章了解更多详细内容。

67

2025.08.05

json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

415

2023.08.07

excel表格操作技巧大全 表格制作excel教程
excel表格操作技巧大全 表格制作excel教程

Excel表格操作的核心技巧在于 熟练使用快捷键、数据处理函数及视图工具,如Ctrl+C/V(复制粘贴)、Alt+=(自动求和)、条件格式、数据验证及数据透视表。掌握这些可大幅提升数据分析与办公效率,实现快速录入、查找、筛选和汇总。

0

2026.01.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 9万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 9万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号