mongodb中如何处理部分周数据分组
我有一些文件(股票每日开盘价)如下:mongodb中如何处理部分周数据分组,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我有一些文件(股票每日开盘价)如下: /* 0 */ { "_id" : ObjectId("54d65597daf0910dfa8169b0"), "D" : ISODate("2014-12-29T00:00:00.000Z"), "O" : 104.98 } /* 1 */ { "_id" : ObjectId("54d65597daf0910dfa8169af"), "D" : ISODate("2014-12-30T00:00:00.000Z"
/* 0 */
{
"_id" : ObjectId("54d65597daf0910dfa8169b0"),
"D" : ISODate("2014-12-29T00:00:00.000Z"),
"O" : 104.98
}
/* 1 */
{
"_id" : ObjectId("54d65597daf0910dfa8169af"),
"D" : ISODate("2014-12-30T00:00:00.000Z"),
"O" : 104.73
}
/* 2 */
{
"_id" : ObjectId("54d65597daf0910dfa8169ae"),
"D" : ISODate("2014-12-31T00:00:00.000Z"),
"O" : 104.51
}
/* 3 */
{
"_id" : ObjectId("54d65597daf0910dfa8169ad"),
"D" : ISODate("2015-01-02T00:00:00.000Z"),
"O" : 103.75
}
/* 4 */
{
"_id" : ObjectId("54d65597daf0910dfa8169ac"),
"D" : ISODate("2015-01-05T00:00:00.000Z"),
"O" : 102.5
}
我想每周汇总记录,这样我就可以得到每周平均开盘价。我的第一次尝试是使用:
db.ohlc.aggregate({
$match: {
D: {
$gte: new ISODate('2014-12-28')
}
}
}, {
$project: {
year: {
$year: '$D'
},
week: {
$week: '$D'
},
O: 1
}
}, {
$group: {
_id: {
year: '$year',
week: '$week'
},
O: {
$avg: '$O'
}
}
}, {
$sort: {
_id: 1
}
})
Bu I很快意识到结果不正确,因为2014年最后一周(第52周)和2015年第一周(第0周)都是部分周。通过此汇总,我将得到2014年12月29日至12月31日的平均价格,以及2015年2月1日(这是2015年第一周的唯一交易日)的平均价格,但在我的应用程序中,我需要对2015年12月29日至2015年2月1日的数据进行分组。有什么建议吗?要回答我自己的问题,诀窍是根据参考日期(1970-01-04)计算周数,并根据该数字分组。有关详细信息,请访问我的新帖子。根据我的经验,这并不是解决问题的好方法。为什么?这绝对不会扩展,所需的计算量非常消耗,特别是在分组时 在您的情况下,我要做的是将应用程序逻辑的一部分移动到数据库中的文档中 我的第一种方法是添加一个“week”字段,该字段将说明样本所属日期的前一个(或下一个)星期日。这在插入时非常容易做到。然后,您可以简单地按该字段运行聚合方法分组。如果您想要更高的性能,请为
{symbol:1,week:1}
添加索引,并在聚合中进行排序
我的第二种方法是,如果你计划进行大量这种类型的聚合,基本上是用文档每周对样本进行分组。像这样:
{
week : <Day Representing Week>,
prices: [
{ Day Sample }, ...
]
}
{
周:,
价格:[
{日样本}。。。
]
}
然后您可以直接处理这些文档。这将有助于显著地减少索引,从而加快速度。我将其用于
烛光化
使用allowDiskUsage
,out和一些日期过滤器,效果非常好。也许你可以采用分组法
db.getCollection('market').aggregate(
[
{ $match: { date: { $exists: true } } },
{ $sort: { date: 1 } },
{ $project: { _id: 0, date: 1, rate: 1, amount: 1, tm15: { $mod: [ "$date", 900 ] } } },
{ $project: { _id: 0, date: 1, rate: 1, amount: 1, candleDate: { $subtract: [ "$date", "$tm15" ] } } },
{ $group: { _id: "$candleDate", open: { $first: '$rate' }, low: { $min: '$rate' }, high: { $max: '$rate' }, close: { $last: '$rate' }, volume: { $sum: '$amount' }, trades: { $sum: 1 } } }
])
我很好奇,为什么我的问题会被否决?我很乐意找出原因。通过添加预计算字段(周)来加快查询速度是正确的。然而,性能提升不是很显著(纯分组为0.75s,预计算字段为0.4s),但我仍然遵循您的第一个建议,添加了一个基于我帖子中方法计算的week字段。该值是在将数据导入db时使用awk计算的(我不得不说,这比mongodb简单得多)。我的收藏有超过6100万个文档,并且有复合索引{S:1,D:1}。我没有使用你的第二个建议,因为分组的周数需要是动态的。你有没有机会解释一下?我试着让它在贸易数据上工作,想用5、10、15分钟的蜡烛等进行分组。。但是没有起作用。日期是多少。。Unix时间毫秒?你能展示一些输入文档样本吗?非常感谢。