mongoDB 时间戳聚合 nodejs mongoose
mongoDB timestamp aggregation nodejs mongoose
我已经搜索了一段时间,并没有真正找到足够明确的答案来理解如何去做。
我将图表数据保存在 MongoDB 中,以分钟为基准(Unix 时间戳)。现在我明白了,如果我想以每小时或每天为基础可视化图表,我需要聚合数据,但我并不完全理解需要做什么。
我想创建 1 小时和 1 天的组,这些组需要包含其时间范围的最后一条记录。然后聚合是否需要完成一次并保存到数据库?或者每次我查询它。以及如何在 mongoose 中设置查询?
这里是我收集的图表数据的例子
collection:[
{
time: 1649083392,
volume: '20384.28',
open: 444.42,
close: 444.56,
high: 444.76,
low: 444.36
},
{
time: 1649083448,
volume: '20384.28',
open: 444.42,
close: 444.56,
high: 444.76,
low: 444.36
},
{
time: 1649083501,
volume: '20384.28',
open: 444.42,
close: 444.56,
high: 444.76,
low: 444.36
}
]
假设我需要一个每天时间表的图表。一天有1440分钟
我首先需要每天做一个组来累加每天的体积,然后投影每天的最后一个项目。它应该预测每天的数量和每天的最后一项。
希望有人能向我解释一下这是如何工作的。谢谢
----更新---
对不起。所以我弄错了。
[{
"pairAddress": "0x58F876857a02D6762E0101bb5C46A8c1ED44Dc16",
"chart": [
{
"time": 1648978488,
"high": "442.93181339228767",
"low": "440.89881857342505",
"open": "440.89901371910537",
"close": "442.9168809785855",
"marketcap": "2505922284.61",
"volume": "14264.118014884118",
"_id": {
"$oid": "62496a3b8741c95e7661a0c2"
}
},
{
"time": 1648978536,
"high": "442.9603776582797",
"low": "442.9122490168528",
"open": "442.9292814855807",
"close": "442.9478700257827",
"marketcap": "2506097613.54",
"volume": "19482.73456302384",
"_id": {
"$oid": "62496a778741c95e7661a971"
}
},
{
"time": 1648978608,
"high": "442.9893218041529",
"low": "442.941310936878",
"open": "442.9481594715175",
"close": "442.9893218041529",
"marketcap": "2506332138.21",
"volume": "16138.024513587941",
"_id": {
"$oid": "62496ab38741c95e7661b53a"
}
},
{
"time": 1648978668,
"high": "443.5010551781398",
"low": "442.9032561370158",
"open": "442.9893789835573",
"close": "443.5010551781398",
"marketcap": "2509227408.46",
"volume": "24664.532500429723",
"_id": {
"$oid": "62496aef8741c95e7661c000"
}
},
{
"time": 1648978728,
"high": "443.5205214040826",
"low": "443.4918353053875",
"open": "443.50216033083433",
"close": "443.5202071089899",
"marketcap": "2509335765.70",
"volume": "5548.645723580672",
"_id": {
"$oid": "62496b2b8741c95e7661c951"
}
},
{
"time": 1648978788,
"high": "443.6375372213781",
"low": "443.470378539243",
"open": "443.50698654937736",
"close": "443.5999403093497",
"marketcap": "2509786877.88",
"volume": "52212.176474500986",
"_id": {
"$oid": "62496b678741c95e7661d396"
}
},
{
"time": 1648978848,
"high": "443.61143763713756",
"low": "443.58718500668306",
"open": "443.59987943714646",
"close": "443.5872533304441",
"marketcap": "2509715097.86",
"volume": "14691.325842608467",
"_id": {
"$oid": "62496ba38741c95e7661e2d3"
}
}
]
}]
这是我文档的实际示例,我需要在图表数组上进行聚合。使用现有代码我无法让它工作。
db.collection.aggregate([
{
$sort: { time: -1 }
},
{
$set: {
d: { $toDate: { $multiply: [ "$time", 1000 ] } },
volume: { $toDecimal: "$volume" }
}
},
{
$facet: {
day: [
{
$group: {
_id: {
$dateTrunc: {
date: "$d",
unit: "day"
}
},
volume: { $sum: "$volume" },
lastItem: { $first: "$$ROOT" }
}
}
],
hour: [
{
$group: {
_id: {
year: { $year: "$d" },
dayOfYear: { $dayOfYear: "$d" },
hour: { $hour: "$d" }
},
volume: { $sum: "$volume" },
lastItem: { $first: "$$ROOT" }
}
}
],
15min: [
{
$group: {
_id: {
year: { $year: "$d" },
dayOfYear: { $dayOfYear: "$d" },
hour: { $hour: "$d" },
interval: {
$subtract: [
{ $minute: "$d" },
{ $mod: [ { $minute: "$d" }, 15 ] }
]
}
},
volume: { $sum: "$volume" },
lastItem: { $first: "$$ROOT" }
}
}
]
}
}
])
我知道这已经得到解答,但我的做法是将时间戳设置为间隔,然后根据时间戳边界对数据进行分组
db.data.aggregate([
{
$addFields: {
// Your Group Interval In Seconds eg.
// - 86400 For Per Day
// - 3600 Per Hour
// - 900 Per 15 minute
timestampBoundary: {
$subtract: ["$time", {$mod: ["$time", 3600]}]
},
}
},
{
$sort: {
time: -1
}
},
{
$group: {
_id: "$timestampBoundary",
lastItem: {$first: "$$ROOT"},
totalVolume: {
$sum: {
$toDecimal: "$volume"
}
},
}
}
])
所以,我对此仍有疑问,因为需要聚合的数据位于文档数组中。
我找到了 $unwind 函数来解决这个问题。
Chart.aggregate([
{$match:{"pairAddress": "0x58F876857a02D6762E0101bb5C46A8c1ED44Dc16"}},
{$unwind: "$chart"},
{$addFields: {
timestampBoundary: {$subtract: ["$chart.time",{$mod: ["$chart.time", 900]}]},
}},
{$sort: {"chart.time": -1}},
{$group: {
_id: "$timestampBoundary",
lastItem: {$first: "$$ROOT"},
volume: {$sum: {$toDecimal: "$chart.volume"}}
}},
{$sort:{ _id: 1}}
])
首先我使用 $match 来确保我只得到我想要聚合的文档,
展开我要聚合的图表数组。然后添加一个新字段将 UNIX 时间戳转换为按时间戳排序。之后我可以按时间戳排序并制作
一组指定的时间间隔。将每组的体积相加并进行最后排序。在 $mod: 900 代表秒,这是我可以指定组的时间间隔的地方。
感谢@YuTing 和@Calvin Coomer 我现在得到了完美的解决方案。
我已经搜索了一段时间,并没有真正找到足够明确的答案来理解如何去做。 我将图表数据保存在 MongoDB 中,以分钟为基准(Unix 时间戳)。现在我明白了,如果我想以每小时或每天为基础可视化图表,我需要聚合数据,但我并不完全理解需要做什么。
我想创建 1 小时和 1 天的组,这些组需要包含其时间范围的最后一条记录。然后聚合是否需要完成一次并保存到数据库?或者每次我查询它。以及如何在 mongoose 中设置查询?
这里是我收集的图表数据的例子
collection:[
{
time: 1649083392,
volume: '20384.28',
open: 444.42,
close: 444.56,
high: 444.76,
low: 444.36
},
{
time: 1649083448,
volume: '20384.28',
open: 444.42,
close: 444.56,
high: 444.76,
low: 444.36
},
{
time: 1649083501,
volume: '20384.28',
open: 444.42,
close: 444.56,
high: 444.76,
low: 444.36
}
]
假设我需要一个每天时间表的图表。一天有1440分钟
我首先需要每天做一个组来累加每天的体积,然后投影每天的最后一个项目。它应该预测每天的数量和每天的最后一项。
希望有人能向我解释一下这是如何工作的。谢谢
----更新---
对不起。所以我弄错了。
[{
"pairAddress": "0x58F876857a02D6762E0101bb5C46A8c1ED44Dc16",
"chart": [
{
"time": 1648978488,
"high": "442.93181339228767",
"low": "440.89881857342505",
"open": "440.89901371910537",
"close": "442.9168809785855",
"marketcap": "2505922284.61",
"volume": "14264.118014884118",
"_id": {
"$oid": "62496a3b8741c95e7661a0c2"
}
},
{
"time": 1648978536,
"high": "442.9603776582797",
"low": "442.9122490168528",
"open": "442.9292814855807",
"close": "442.9478700257827",
"marketcap": "2506097613.54",
"volume": "19482.73456302384",
"_id": {
"$oid": "62496a778741c95e7661a971"
}
},
{
"time": 1648978608,
"high": "442.9893218041529",
"low": "442.941310936878",
"open": "442.9481594715175",
"close": "442.9893218041529",
"marketcap": "2506332138.21",
"volume": "16138.024513587941",
"_id": {
"$oid": "62496ab38741c95e7661b53a"
}
},
{
"time": 1648978668,
"high": "443.5010551781398",
"low": "442.9032561370158",
"open": "442.9893789835573",
"close": "443.5010551781398",
"marketcap": "2509227408.46",
"volume": "24664.532500429723",
"_id": {
"$oid": "62496aef8741c95e7661c000"
}
},
{
"time": 1648978728,
"high": "443.5205214040826",
"low": "443.4918353053875",
"open": "443.50216033083433",
"close": "443.5202071089899",
"marketcap": "2509335765.70",
"volume": "5548.645723580672",
"_id": {
"$oid": "62496b2b8741c95e7661c951"
}
},
{
"time": 1648978788,
"high": "443.6375372213781",
"low": "443.470378539243",
"open": "443.50698654937736",
"close": "443.5999403093497",
"marketcap": "2509786877.88",
"volume": "52212.176474500986",
"_id": {
"$oid": "62496b678741c95e7661d396"
}
},
{
"time": 1648978848,
"high": "443.61143763713756",
"low": "443.58718500668306",
"open": "443.59987943714646",
"close": "443.5872533304441",
"marketcap": "2509715097.86",
"volume": "14691.325842608467",
"_id": {
"$oid": "62496ba38741c95e7661e2d3"
}
}
]
}]
这是我文档的实际示例,我需要在图表数组上进行聚合。使用现有代码我无法让它工作。
db.collection.aggregate([
{
$sort: { time: -1 }
},
{
$set: {
d: { $toDate: { $multiply: [ "$time", 1000 ] } },
volume: { $toDecimal: "$volume" }
}
},
{
$facet: {
day: [
{
$group: {
_id: {
$dateTrunc: {
date: "$d",
unit: "day"
}
},
volume: { $sum: "$volume" },
lastItem: { $first: "$$ROOT" }
}
}
],
hour: [
{
$group: {
_id: {
year: { $year: "$d" },
dayOfYear: { $dayOfYear: "$d" },
hour: { $hour: "$d" }
},
volume: { $sum: "$volume" },
lastItem: { $first: "$$ROOT" }
}
}
],
15min: [
{
$group: {
_id: {
year: { $year: "$d" },
dayOfYear: { $dayOfYear: "$d" },
hour: { $hour: "$d" },
interval: {
$subtract: [
{ $minute: "$d" },
{ $mod: [ { $minute: "$d" }, 15 ] }
]
}
},
volume: { $sum: "$volume" },
lastItem: { $first: "$$ROOT" }
}
}
]
}
}
])
我知道这已经得到解答,但我的做法是将时间戳设置为间隔,然后根据时间戳边界对数据进行分组
db.data.aggregate([
{
$addFields: {
// Your Group Interval In Seconds eg.
// - 86400 For Per Day
// - 3600 Per Hour
// - 900 Per 15 minute
timestampBoundary: {
$subtract: ["$time", {$mod: ["$time", 3600]}]
},
}
},
{
$sort: {
time: -1
}
},
{
$group: {
_id: "$timestampBoundary",
lastItem: {$first: "$$ROOT"},
totalVolume: {
$sum: {
$toDecimal: "$volume"
}
},
}
}
])
所以,我对此仍有疑问,因为需要聚合的数据位于文档数组中。
我找到了 $unwind 函数来解决这个问题。
Chart.aggregate([
{$match:{"pairAddress": "0x58F876857a02D6762E0101bb5C46A8c1ED44Dc16"}},
{$unwind: "$chart"},
{$addFields: {
timestampBoundary: {$subtract: ["$chart.time",{$mod: ["$chart.time", 900]}]},
}},
{$sort: {"chart.time": -1}},
{$group: {
_id: "$timestampBoundary",
lastItem: {$first: "$$ROOT"},
volume: {$sum: {$toDecimal: "$chart.volume"}}
}},
{$sort:{ _id: 1}}
])
首先我使用 $match 来确保我只得到我想要聚合的文档, 展开我要聚合的图表数组。然后添加一个新字段将 UNIX 时间戳转换为按时间戳排序。之后我可以按时间戳排序并制作 一组指定的时间间隔。将每组的体积相加并进行最后排序。在 $mod: 900 代表秒,这是我可以指定组的时间间隔的地方。
感谢@YuTing 和@Calvin Coomer 我现在得到了完美的解决方案。