Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在复杂的数据结构中为MongoDB时间序列数据编写单个fire and forget$inc查询_Mongodb - Fatal编程技术网

如何在复杂的数据结构中为MongoDB时间序列数据编写单个fire and forget$inc查询

如何在复杂的数据结构中为MongoDB时间序列数据编写单个fire and forget$inc查询,mongodb,Mongodb,提前感谢您帮助我解决MongoDB时间序列数据问题 场景 我正在为类似Slack/Discord的聊天应用程序编写分析功能。有许多“聊天服务器”,它们有许多频道,许多用户可以输入这些频道 对于每个聊天服务器,我希望在每次向频道中键入消息时,增加每个用户、每个频道、每个小时、每个月的消息数 我想每个聊天服务器每月都有一个文档,这样我就可以在一年后自动过期/删除文档,以便尝试限制每个文档的大小(不包括每个月)和整个集合。但我很想听听你的想法 目标 我想在网站上以图表的形式显示这些数据,在适用的情况下

提前感谢您帮助我解决MongoDB时间序列数据问题

场景

我正在为类似Slack/Discord的聊天应用程序编写分析功能。有许多“聊天服务器”,它们有许多频道,许多用户可以输入这些频道

对于每个聊天服务器,我希望在每次向频道中键入消息时,增加每个用户、每个频道、每个小时、每个月的消息数

我想每个聊天服务器每月都有一个文档,这样我就可以在一年后自动过期/删除文档,以便尝试限制每个文档的大小(不包括每个月)和整个集合。但我很想听听你的想法

目标

我想在网站上以图表的形式显示这些数据,在适用的情况下,每个月都是x轴数据点。 我需要的查询类型包括:

  • 过去12个月内每月所有聊天服务器的所有消息的总和
  • 过去12个月内每个聊天服务器中每月所有消息的总和
  • 过去6个月内每月最活跃的聊天服务器
  • 当月单个聊天服务器中最活跃的频道
  • 当月单个聊天服务器中最活跃的用户
  • 增加这些计数的查询必须是一个单一的fire-and-forget查询 将在数据不存在的地方设置/创建数据的查询
建议的数据结构

通过阅读,我得出了以下数据结构,允许我按服务器id和月份进行索引:

{
    server_id: "1234567890",
    month: ISODate("2019-09-01T00:00:00.000Z"),
    days: [{
        day: ISODate("2019-09-01T00:00:00.000Z"),
        hours: [{
            hour: ISODate("2019-09-01T00:01:00.000Z"),
            channels: [{
                channel_id: "405983",
                users: [{
                    user_id: "111111",
                    messages: 44
                }, {
                    user_id: "333333",
                    messages: 87
                }]
            }]
        }, {
            hour: ISODate("2019-09-01T00:02:00.000Z"),
            channels: [{
                channel_id: "405983",
                users: [{
                    user_id: "111111",
                    messages: 33
                }, {
                    user_id: "333333",
                    messages: 22
                }]
            }]
        }]
    }]
}
尝试的查询:

db.analytics.update({
    guild_id: "619633147906097194",
    "days.hours.channels.channel_id": "903488"
}, {
    $inc: {
        "days.11.hours.16.channels.$[].messages": 1
    }
}, {
    upsert: true
})
然而,我不能让它工作。错误: 要应用阵列更新,文档中必须存在路径“days.11.hours.16.channels”

问题

  • 对于查询的性能,是否有更好的数据结构 我想写信
  • 每月为每个聊天服务器创建一个新文档是一个好主意吗 还是有更好的办法
  • 单个fire-and-forget查询将是什么样子的
    增加消息计数(编写此消息的任何帮助都将是 谢谢,这有点超出我目前的知识范围
  • 是我需要编写以显示数据的聚合查询 有意义地以图形形式呈现,此数据结构在 每个图一次查询
  • 谢谢你!

    你可以使用蒙戈来做这件事,但是考虑一下你试图随着时间的推移看到这些数据的事实,所以你将不得不解决他们在时间序列数据库中已经解决的相同问题。

    考虑到这样一个事实,即您将不断写入并锁定该表,因此mongo集群中的主要通信量将只是该表复制到从属服务器。然后,无论何时您的用户想要查看这些数据,您都需要对您的应用程序数据库运行一个查询—并且如果从由于写入负载很重,您的读取时间可能需要一段时间

    当您想要绘制时间序列数据时,您可能希望使用时间序列数据库作为度量标准。它使以后访问/聚合信息变得更轻松,您可以根据时间绘制更详细的图形,并且现有的工具可以让您轻松地在仪表板上可视化数据y

    使用单独的度量数据库和应用程序数据库的优点是,您的报告可以根据需要进行密集处理,并且您的最终用户永远不会受到影响

    您可以为每个聊天事件发送带有时间戳和数据标签的记录,并在应用程序数据库中保留较重的元素(例如聊天文本)。您可以添加任意多的字段,并且所有字段都可以绘制

    你可以考虑,或者两者都可以很容易地用图形绘制。使用GravaNA直接在蒙哥上是很棘手的。

    如果您关心第二次数据库写入的性能开销,您可以创建一个连接到度量数据库的sidecar进程/线程。使用通道/队列(RabbitMQ、Celery、SQS)/任何东西与线程异步通信,它将负责完成对度量服务器的写入

    如果您不太在意精度,可以使用prometheus/statsd,它擅长聚合数据和显示模式。这些工具性能很高,但用于监控数据(随着时间的推移价值会下降),而不是业务数据(在业务数据中,每年的数据精度比较可能很有价值)