如何在复杂的数据结构中为MongoDB时间序列数据编写单个fire and forget$inc查询
提前感谢您帮助我解决MongoDB时间序列数据问题 场景 我正在为类似Slack/Discord的聊天应用程序编写分析功能。有许多“聊天服务器”,它们有许多频道,许多用户可以输入这些频道 对于每个聊天服务器,我希望在每次向频道中键入消息时,增加每个用户、每个频道、每个小时、每个月的消息数 我想每个聊天服务器每月都有一个文档,这样我就可以在一年后自动过期/删除文档,以便尝试限制每个文档的大小(不包括每个月)和整个集合。但我很想听听你的想法 目标 我想在网站上以图表的形式显示这些数据,在适用的情况下,每个月都是x轴数据点。 我需要的查询类型包括:如何在复杂的数据结构中为MongoDB时间序列数据编写单个fire and forget$inc查询,mongodb,Mongodb,提前感谢您帮助我解决MongoDB时间序列数据问题 场景 我正在为类似Slack/Discord的聊天应用程序编写分析功能。有许多“聊天服务器”,它们有许多频道,许多用户可以输入这些频道 对于每个聊天服务器,我希望在每次向频道中键入消息时,增加每个用户、每个频道、每个小时、每个月的消息数 我想每个聊天服务器每月都有一个文档,这样我就可以在一年后自动过期/删除文档,以便尝试限制每个文档的大小(不包括每个月)和整个集合。但我很想听听你的想法 目标 我想在网站上以图表的形式显示这些数据,在适用的情况下
- 过去12个月内每月所有聊天服务器的所有消息的总和
- 过去12个月内每个聊天服务器中每月所有消息的总和
- 过去6个月内每月最活跃的聊天服务器
- 当月单个聊天服务器中最活跃的频道
- 当月单个聊天服务器中最活跃的用户
- 增加这些计数的查询必须是一个单一的fire-and-forget查询 将在数据不存在的地方设置/创建数据的查询
{
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”
问题
增加消息计数(编写此消息的任何帮助都将是 谢谢,这有点超出我目前的知识范围
谢谢你!
你可以使用蒙戈来做这件事,但是考虑一下你试图随着时间的推移看到这些数据的事实,所以你将不得不解决他们在时间序列数据库中已经解决的相同问题。 考虑到这样一个事实,即您将不断写入并锁定该表,因此mongo集群中的主要通信量将只是该表复制到从属服务器。然后,无论何时您的用户想要查看这些数据,您都需要对您的应用程序数据库运行一个查询—并且如果从由于写入负载很重,您的读取时间可能需要一段时间 当您想要绘制时间序列数据时,您可能希望使用时间序列数据库作为度量标准。它使以后访问/聚合信息变得更轻松,您可以根据时间绘制更详细的图形,并且现有的工具可以让您轻松地在仪表板上可视化数据y 使用单独的度量数据库和应用程序数据库的优点是,您的报告可以根据需要进行密集处理,并且您的最终用户永远不会受到影响 您可以为每个聊天事件发送带有时间戳和数据标签的记录,并在应用程序数据库中保留较重的元素(例如聊天文本)。您可以添加任意多的字段,并且所有字段都可以绘制你可以考虑,或者两者都可以很容易地用图形绘制。使用GravaNA直接在蒙哥上是很棘手的。
如果您关心第二次数据库写入的性能开销,您可以创建一个连接到度量数据库的sidecar进程/线程。使用通道/队列(RabbitMQ、Celery、SQS)/任何东西与线程异步通信,它将负责完成对度量服务器的写入 如果您不太在意精度,可以使用prometheus/statsd,它擅长聚合数据和显示模式。这些工具性能很高,但用于监控数据(随着时间的推移价值会下降),而不是业务数据(在业务数据中,每年的数据精度比较可能很有价值)