我一直在寻找解决方案好几天,但我无法得到结果。拜托,帮助我!
我在MongoDB中有一个数据:
{ name: 'apple', date: 2018-01-04T10:00:00.000Z, price: 100 }
{ name: 'apple', date: 2018-01-04T10:01:00.000Z, price: 101 }
{ name: 'apple', date: 2018-01-04T10:02:00.000Z, price: 102 }
{ name: 'apple', date: 2018-01-04T10:03:00.000Z, price: 103 }
{ name: 'apple', date: 2018-01-04T10:04:00.000Z, price: 102 }
{ name: 'apple', date: 2018-01-04T10:05:00.000Z, price: 104 }
{ name: 'cherry', date: 2018-01-04T10:00:00.000Z, price: 53 }
{ name: 'cherry', date: 2018-01-04T10:01:00.000Z, price: 55 }
{ name: 'cherry', date: 2018-01-04T10:02:00.000Z, price: 51 }
{ name: 'cherry', date: 2018-01-04T10:03:00.000Z, price: 51 }
{ name: 'cherry', date: 2018-01-04T10:04:00.000Z, price: 50 }
{ name: 'cherry', date: 2018-01-04T10:05:00.000Z, price: 52 }
{ name: 'melon', date: 2018-01-04T10:00:00.000Z, price: 133 }
{ name: 'melon', date: 2018-01-04T10:01:00.000Z, price: 132 }
{ name: 'melon', date: 2018-01-04T10:02:00.000Z, price: 136 }
{ name: 'melon', date: 2018-01-04T10:03:00.000Z, price: 137 }
{ name: 'melon', date: 2018-01-04T10:04:00.000Z, price: 138 }
{ name: 'melon', date: 2018-01-04T10:05:00.000Z, price: 140 }
我希望通过一个查询得到这个结果。
{name: 'apple', price_last: 104, price_1m_ago: 102, price_5m_ago: 100}
{name: 'cherry', price_last: 52, price_1m_ago: 50, price_5m_ago: 53}
{name: 'melon', price_last: 140, price_1m_ago: 138, price_5m_ago: 133}
我尝试使用聚合但我无法以任何方式构建有效的查询。
food.aggregate([
{
$group: {
_id: "$name",
price_last: {$last:"$price"},
}
}
]}
答案 0 :(得分:0)
如果您的数据保证每分钟包含一个元素且中间没有丢失的数据,则可以非常轻松地实现这一点:
food.aggregate([{
$sort: {
date: 1 // make sure the data is sorted by date
}
}, {
$group: {
_id: "$name",
prices: { $push: "$price" }, // create an array per "name" with all prices in it
}
}, {
$project: {
name: "$_id",
price_last: { $arrayElemAt: [ "$prices", -1 ] }, // select the first from the end of the array
price_1m_ago: { $arrayElemAt: [ "$prices", -2 ] }, // select the second from the end
price_5m_ago: { $arrayElemAt: [ "$prices", -6 ] } // select the 6th from the end
}
}])
答案 1 :(得分:0)
我用@Avij第一个查询得到了这个结果。这是一些重复。如果我更换$ minute:' $ lastdate'使用新的Date(),查询无效。
{ _id: 'melon',
lastPrice: 1575,
five_min_price: 1573 },
{ _id: 'cherry',
lastPrice: 60165,
five_min_price: 59098 },
{ _id: 'apple',
lastPrice: 0153,
five_min_price: 0155 },
{ _id: 'apple',
lastPrice: 0153,
five_min_price: 0154 },
{ _id: 'apple',
lastPrice: 0153,
five_min_price: 0155 },
{ _id: 'apricot',
lastPrice: 6897,
five_min_price: 6235 },
{ _id: 'apricot',
lastPrice: 6897,
five_min_price: 6235 },
{ _id: 'apricot',
lastPrice: 6897,
five_min_price: 6822 },
{ _id: 'apricot',
lastPrice: 6897,
five_min_price: 683 },
{ _id: 'cucumber',
lastPrice: 3461,
five_min_price: 3533 },
{ _id: 'cucumber',
lastPrice: 3461,
five_min_price: 3496 },
{ _id: 'orange',
lastPrice: 5366,
five_min_price: 5367 }
也许可以使用$ match查询查询,然后在此结果中获得最后一个。如果DB中的日期存储在Unix格式中。这项工作只有一个结果,但我如何得到10s / 30s / 1m / 5m / 10m / 30m / 1h会产生一个查询。
var now = new Date();
var shift_5_min = shift_5_min = new Date( now.valueOf() - ( 5*60*1000 );
"$match": {
"date": { "$lte": shift_5_min" }
}
$group: {
id: "$name",
price: {$last: "$price"}
}