我有一个具有以下结构的MongoDB集合:
Prices: [
exchange, symbol, volume, buy, sell, last, low, high
]
我使用Mongoose查询记录,我希望在过去3小时内按照符号分组获得买入,卖出,持续,低,高的平均值。
基本上我的目标是展示如下内容: (设A,B,C,D,E,F为数字的占位符)
Latest Prices for Exchange:
Symbol A Volume: A Buy: B Sell: C Last: D Low: E High: F Spread: C - B
Symbol B Volume: A Buy: B Sell: C Last: D Low: E High: F Spread: C - B
3 Hour Averages for Exchange:
Symbol A: Volume: A Buy: B Sell: C Last: D Low: E High: F Spread: C - B
Symbol B: Volume: X Buy: B Sell: C Last: D Low: E High: F Spread: C - B
我一直在阅读MongoDB文档: https://docs.mongodb.org/manual/reference/operator/aggregation/group/
为了获得平均值,我尝试过这样的事情:
query = Prices.aggregate([
{
$group: {
_id: "$symbol",
avg_last: { $avg: "$last" },
avg_buy: { $avg: "$buy" },
avg_sell: { $avg: "$sell" },
avg_low: { $avg: "$low" },
avg_high: { $avg: "$high" },
averageSpread: { $avg: { $subtract: ["$sell", "$buy"] } },
count: { $sum: 1 }
}
}
]);
问题在于,没有“条件”将结果限制为过去3小时。
再次使用MongoDB文档获取$ cond https://docs.mongodb.org/manual/reference/operator/aggregation/cond/
我试图应用这个:
var threeHoursAgo = new Date();
threeHoursAgo.setHours(threeHoursAgo.getHours() - 3);
query = Prices.aggregate([
{
$group: {
_id: "$symbol",
avg_last: { $avg: "$last" },
avg_buy: { $avg: "$buy" },
avg_sell: { $avg: "$sell" },
avg_low: { $avg: "$low" },
avg_high: { $avg: "$high" },
averageSpread: { $avg: { $subtract: ["$sell", "$buy"] } },
count: { $sum: 1 }
},
$cond: {
exchange: strategy.primaryExchanges[i].exchange._id,
timestamp: {
$gte: threeHoursAgo
}
}
}
]);
但我收到以下错误:
"Error: Arguments must be aggregate pipline operators".
编辑:我也尝试使用$ match,如:
query = Prices.aggregate([
{
$group: {
_id: "$symbol",
avg_last: { $avg: "$last" },
avg_buy: { $avg: "$buy" },
avg_sell: { $avg: "$sell" },
avg_low: { $avg: "$low" },
avg_high: { $avg: "$high" },
averageSpread: { $avg: { $subtract: ["$sell", "$buy"] } },
count: { $sum: 1 }
}
},
{
$match: {
$and: [
{exchange: strategy.primaryExchanges[i].exchange._id},
{timestamp: {$gte: threeHoursAgo} }
]
}
}
]);
但我得到一个空数组。
编辑2 以下是我的价格集合中的示例文档:
{"_id":"ObjectId(56296ac0603c75c80b3d581f)","symbol":"XBT24H","contract":"XBT24H","exchange":"ObjectId(55dc8ae9ecb73538125ddd9a)","timestamp":"ISODate(2015-10-22T23:01:15.000Z)","volume":260475,"buy":275.41,"sell":275.7,"low":274.44,"last":275.7,"high":277.03,"__v":0}
答案 0 :(得分:2)
我已经找到了解决方案。
问题是我的$ match声明。必须在我的$ group声明之前
query = Prices.aggregate([
{
$match: {
$and: [
{exchange: strategy.primaryExchanges[i].exchange._id},
{timestamp: {$gte: threeHoursAgo} }
]
}
},
{
$group: {
_id: "$symbol",
avg_last: { $avg: "$last" },
avg_buy: { $avg: "$buy" },
avg_sell: { $avg: "$sell" },
avg_low: { $avg: "$low" },
avg_high: { $avg: "$high" },
averageSpread: { $avg: { $subtract: ["$sell", "$buy"] } },
count: { $sum: 1 }
}
}
]);
这可以工作并返回我期待的结果。