Lar*el数据库通知的智能管理:实现通知合并与去重


laravel数据库通知的智能管理:实现通知合并与去重

在Lar*el应用中,当短时间内有大量事件触发通知时,用户可能会收到过多的重复或相似通知,导致体验不佳。本文将详细介绍如何通过优化Lar*el的数据库通知机制,实现在特定时间窗口内合并或更新现有通知,而非创建新的通知,从而有效减少通知数量,提升用户体验。

引言:优化通知体验的必要性

在现代Web应用中,通知是与用户互动的重要手段。然而,如果通知系统设计不当,例如在短时间内针对同一事件或同一类事件发送大量独立通知,用户体验将大打折扣,可能导致“通知疲劳”,甚至让用户选择关闭通知功能。为了解决这一问题,我们需要一种机制,能够在特定条件下对通知进行“去重”或“合并”,例如,在30分钟内,将关于同一主题的多个通知合并为一个,只更新其计数或内容。

Lar*el数据库通知基础

Lar*el的通知系统提供了一个便捷的方式来向用户发送各类通知。对于数据库通知,我们通常会在通知类的 toDatabase 方法中定义要存储到 notifications 表中的数据。当 Notification::send() 方法被调用时,Lar*el会调用相应渠道(如 toDatabase)的方法,并将其返回的数据存储起来。

toDatabase 方法的典型结构如下:

public function toDatabase($notifiable): array
{
    return [
        'content' => '这是一条新通知',
        'type' => 'post_created',
        'post_id' => $this->post->id,
    ];
}

Lar*el会将这个返回的数组存储到 notifications 表的 data 字段中。

策略:合并或更新现有通知

我们的核心策略是:当一个事件触发通知时,首先检查在预设的时间窗口(例如30分钟)内,是否已经存在一个针对相同主题的通知。

  • 如果存在,则更新这个现有通知的 data 字段(例如,增加一个计数器,或修改通知内容),并阻止创建新的通知。
  • 如果不存在,则创建一条全新的通知。

实现通知合并逻辑

为了实现上述策略,我们需要修改通知类中的 toDatabase 方法。原始的问题代码尝试在找到现有通知后进行更新,但最终仍然会执行方法末尾的 return [] 语句,导致即使更新了旧通知,也会创建一条新通知。

关键在于:当成功更新现有通知后,必须阻止 toDatabase 方法继续返回一个非空的数组,因为任何非空数组都会被Lar*el视为一条新的通知记录来存储。 返回一个空数组 [] 或 null 是阻止新通知创建的有效方式。

下面是优化后的 toDatabase 方法示例:

万彩商图 万彩商图

专为电商打造的AI商拍工具,快速生成多样化的高质量商品图和模特图,助力商家节省成本,解决素材生产难、产图速度慢、场地设备拍摄等问题。

万彩商图 212 查看详情 万彩商图
<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\DatabaseMessage;
use App\Models\Search; // 假设您的Search模型

class PostMatchedSearchNotification extends Notification
{
    use Queueable;

    protected Search $search;
    protected string $postTitle; // 假设通知中需要展示的帖子标题

    /**
     * 创建一个新的通知实例。
     *
     * @param Search $search 触发通知的搜索条件
     * @param string $postTitle 匹配到的帖子标题
     * @return void
     */
    public function __construct(Search $search, string $postTitle = '新帖子')
    {
        $this->search = $search;
        $this->postTitle = $postTitle;
    }

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

    /**
     * 将通知转换为数据库存储的数组。
     *
     * @param mixed $notifiable
     * @return array
     */
    public function toDatabase($notifiable): array
    {
        $timeWindowMinutes = 30; // 定义时间窗口:30分钟
        $searchIdentifier = $this->search->id; // 用于识别相关通知的唯一标识

        // 尝试查找在指定时间窗口内,针对当前搜索条件已存在的通知
        $existingNotification = $notifiable->notifications()
            ->where('data->search_id', $searchIdentifier) // 使用 data->search_id 进行查询
            ->where('created_at', '>=', now()->subMinutes($timeWindowMinutes))
            ->first();

        if ($existingNotification) {
            // 如果找到了现有通知,则更新它
            $currentCount = $existingNotification->data['count'] ?? 0;
            $newCount = $currentCount + 1;

            $existingNotification->update([
                'data' => array_merge($existingNotification->data, [
                    'content' => [
                        'en' => "{$newCount} new posts matched with your s*ed search '{$this->search->title}' h*e been posted. Click to view more.",
                        'zh' => "您的保存搜索 '{$this->search->title}' 匹配到 {$newCount} 篇新帖子。点击查看更多。",
                    ],
                    'count' => $newCount,
                    // 可以更新其他相关数据,例如最后更新时间
                    'last_updated_at' => now()->toDateTimeString(),
                    // 确保 search_id 和 parameters 等关键标识符仍然存在
                    'search_id' => $searchIdentifier,
                    'parameters' => $this->search->parameters,
                ])
            ]);

            // 关键:返回一个空数组,阻止Lar*el创建新的通知记录
            return [];
        }

        // 如果在时间窗口内没有找到现有通知,则创建一条新的通知
        return [
            'content' => [
                'en' => "1 new post matched with your s*ed search '{$this->search->title}' has been posted. Click to view more.",
                'zh' => "您的保存搜索 '{$this->search->title}' 匹配到 1 篇新帖子。点击查看更多。",
            ],
            'count' => 1,
            'search_id' => $searchIdentifier, // 用于后续查询的标识符
            'parameters' => $this->search->parameters,
            'first_matched_post_title' => $this->postTitle, // 首次匹配到的帖子标题
            'created_at' => now()->toDateTimeString(), // 记录创建时间
        ];
    }
}

代码解析:

  1. $timeWindowMinutes = 30;: 定义了通知合并的时间窗口。
  2. $searchIdentifier = $this->search->id;: 定义了一个唯一标识符,用于识别属于同一组的通知。这里使用了 search_id,但在实际应用中,您可以根据业务逻辑选择任何合适的字段(例如 product_id, category_id 等)。
  3. $notifiable->notifications()->where('data->search_id', $searchIdentifier)->where('created_at', '>=', now()->subMinutes($timeWindowMinutes))->first();:
    • $notifiable->notifications(): 获取当前用户(或任何可通知实体)的所有通知。
    • where('data->search_id', $searchIdentifier): 使用JSON列查询语法,查找 data 字段中 search_id 匹配的通知。
    • where('created_at', '>=', now()->subMinutes($timeWindowMinutes)): 限制查询范围,只查找在过去30分钟内创建的通知。这里使用 created_at 是为了确保我们是在一个“新鲜”的时间窗口内进行合并,而不是无限期地更新一个非常老的通知。
    • first(): 获取符合条件的第一条通知。
  4. if ($existingNotification) 块:
    • 如果找到了现有通知,我们从中获取当前的计数 ($existingNotification->data['count'] ?? 0) 并递增。
    • $existingNotification->update(['data' => array_merge(...)]): 使用 array_merge 来合并旧的 data 数据和新的更新数据,这样可以保留 data 字段中其他未修改的信息。更新通知的 data 字段和 updated_at 时间戳。
    • return [];: 这是关键!当通知被成功更新后,返回一个空数组。这会告诉Lar*el的通知系统,不需要再存储一个新的通知记录,从而达到了合并通知的目的。
  5. else 块(即 if 块之后的 return 语句):
    • 如果未找到现有通知(即 $existingNotification 为 null),则意味着这是一个全新的通知事件,此时正常返回一个包含所有通知内容的数组,Lar*el会将其作为一条新记录存储。

进阶考量与最佳实践

  1. created_at 与 updated_at 的选择:

    • 在查询现有通知时,使用 created_at 配合时间窗口 (now()->subMinutes(30)) 是一个常见的做法,它确保我们总是在一个相对较新的通知序列中进行合并。
    • notifications 表自身的 updated_at 字段会在每次更新 data 字段时自动更新,这可以用来追踪通知的活跃度。
    • 您也可以在 data 字段内部维护一个 last_updated_at 字段,以更精细地控制何时“重置”通知周期,即如果距离 last_updated_at 超过30分钟,就创建新通知,否则更新。这与答案中提到的 Last_send 概念类似。
  2. data 字段的设计:

    • 保持 data 字段的结构清晰且一致至关重要。例如,始终包含一个 search_id 或 type 字段,以便于查询和识别相关通知。
    • 对于多语言内容,可以将 content 字段设计为包含不同语言版本的数组,如示例中的 ['en' => '...', 'zh' => '...']。
  3. 性能考量:

    • 对于拥有大量用户的系统,频繁查询 notifications 表可能会带来性能压力。确保 notifications 表上的 notifiable_id, notifiable_type, created_at 字段以及 data 字段中的常用查询键(例如 data->search_id)有合适的索引。
    • 如果通知量特别巨大,可以考虑将通知合并逻辑放在队列中处理,以避免阻塞主请求。
  4. 用户体验:

    • 在前端展示时,需要考虑如何清晰地呈现合并后的通知,例如显示“5篇新帖子”或“X条新消息”等聚合信息。
    • 点击合并通知后,应引导用户到一个聚合页面,展示所有相关的最新内容。
  5. 其他通知渠道:

    • 此方法主要针对数据库通知。如果您的应用还使用了邮件、短信或其他实时通知渠道,则需要为这些渠道单独设计去重或合并逻辑,因为它们的发送机制和存储方式不同。

总结

通过在Lar*el通知类的 toDatabase 方法中引入条件判断和早期返回机制,我们可以有效地实现数据库通知的智能合并与去重。这不仅能够显著减少用户收到的通知数量,避免“通知疲劳”,还能提升整体的用户体验。合理设计 data 字段结构,并结合索引优化,可以确保此方案在不同规模的应用中都能高效运行。

以上就是Lar*el数据库通知的智能管理:实现通知合并与去重的详细内容,更多请关注php中文网其它相关文章!


# laravel  # js  # 前端  # json  # go  # php  # 您的  # 点击查看  # 会在  # 这是  # 并与  # 多语言  # win  # app  # 怎么看  # 济南seo教育培训  # 科技项目策划营销推广  # 低价网站建设选哪家企业  # 银川营销策划推广网站  # 枣庄企业网站关键词推广  # 网站建设资讯  # 进阶  # 是一个  # 则更  # 佛山网站优化设计  # 潮南抖音seo  # seo优化合法吗  # 顺德网站建设哪里有优化 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894 】


相关推荐: Lar*el如何创建自定义的辅助函数(Helpers)_Lar*el全局函数定义与加载方法  谷歌浏览器怎么把网页翻译成中文_Chrome网页翻译功能使用方法  《爱南宁》认证电动车方法  韩小圈网页版PC端入口 韩小圈网页版官方网站入口  AO3中文版手机快速通道_AO3最新稳定链接更新  win11讲述人怎么关闭 Win11屏幕朗读辅助功能禁用方法【技巧】  《东方航空》添加乘机人方法  嘴唇干裂起皮怎么办 唇部护理与预防干裂的方法【详解】  繁花漫画使用教程  realme 10 Pro息屏方案_realme 10 Pro省电策略  抖音猜你想搜能说明对方搜过吗  智学网app怎么登录忘记密码_智学网app忘记密码找回与重新登录操作方法  在Django中动态检查模型关联:一种灵活的解决方案  QQ邮箱PC端登录页面_QQ邮箱网页版登录界面  J*a中的值传递到底指什么_值传递模型在参数传递中的真正含义说明  使用逻辑应用(Logic Apps)自动处理邮件附件中的XML到Excel  斯宾塞称XGP云游戏“蒸蒸日上”:正在构建一个游戏从未如此唾手可得的未来  Yandex浏览器官方入口_Yandex搜索引擎中文版  教资成绩怎么查询  《虎扑》取消评分记录方法  word表格如何按某一列内容进行排序_Word表格按列排序方法  高德地图导航路线偏差报警频繁怎么办 高德地图路线偏差修复与优化方法  解决jQuery多计算器输入字段冲突的教程  TikTok视频播放中断怎么办 TikTok播放异常修复方法  中通快递官网指定查询 中通快递单号查询平台入口  优化 WooCommerce 产品价格显示与自定义短代码集成  高效调试PHP大型嵌套数组:JSON序列化与可视化工具实践  PHP中动态类名访问的类实例类型提示与静态分析实践  cad怎么隐藏指定的图层_cad隐藏或冻结图层方法  网页版网易云音乐入口_网易云音乐在线官网登录  《下一站江湖2》独孤剑诀习得方法  AI图层蒙版怎么用_AI图层蒙版应用技巧与设计实例  《雷电模拟器》自动点击设置方法  OPPO手机参数配置如何开启护眼模式_OPPO手机参数配置护眼模式开启指南  mysql如何配置从库只读_mysql从库只读设置方法  React应用中Commerce.js数据加载与状态管理最佳实践  Word如何将文字快速转成表格 Word文本转换成表格功能使用技巧【效率】  263企业邮箱如何设置邮件转发功能  谷歌邮箱官方入口链接 谷歌邮箱网页版电脑端快速登录  《火花chat》搜索好友方法  实时数据流中高效查找最小值与最大值  抖音号怎么解除企业认证改成个人?改成个人有影响吗?  RxJS中如何高效地在一个函数内处理和合并多个数据集合  折叠屏手机充不进电是什么问题? 特殊结构带来的维修难点  动漫岛在线动漫网 动漫岛动漫在线观看官方入口  《飞猪旅行》购买汽车票方法  招商淘客入门指南  网易云音乐闹钟铃声设置教程  优化 React onClick 事件处理:函数引用与箭头函数的对比  漫蛙官网(首页入口)_漫蛙漫画稳定访问教程分享 

 2025-11-22

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.