Это моя схема
var schema = new mongoose.Schema({
key: String,
value: Number
}, {
timestamps: true
});
У меня есть записи вроде этого (я собираю разные статистические данные)
var entry1 = {
key: "subscribers",
value: 100
}
var entry2 = {
key: "online",
value: 105
}
Я пытаюсь получить все значения времени для каждого ключа. Прямо сейчас у меня это:
var now = new Date();
var startOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate());
db.getConnection().model("MaxValue").aggregate([{
"$match": {
createdAt: {
$gte: startOfToday
}
}
}, {
"$group": {
"_id": "$key",
"value": { "$max": "$value" },
}
}], function(err,result) {
resolve(result)
})
Но я хочу получить созданную дату и для этого значения, потому что я хочу знать, когда было записано это значение.
Это не так просто, потому что $ max является аккумулятором, поэтому вы не можете просто прямо на эту дату перенести результат. Поэтому нам нужно добавить еще несколько этапов трубопровода. К счастью, у нас есть оператор $ addToSet, поэтому мы можем добавлять настраиваемые преобразования для каждой группы.
Поэтому после группировки каждая группа должна по-прежнему содержать даты в сочетании со значениями. Затем мы выполняем размотку для обработки каждого элемента отдельно. Затем мы можем установить новое поле, которое различает, если такой документ содержит максимальное значение в группе. Оператор $ cmp устанавливает это поле равным 0, если строки равны. Наконец, на последнем этапе мы можем отфильтровать документы без максимального значения.
db.maxValues.aggregate([
{
"$group": {
"_id": "$key",
"value": { "$max": "$value" },
"values": { "$addToSet" : { "value": "$value", "createdAt": "$createdAt" }}
}
},
{
"$unwind": "$values"
},
{
"$project": {
"_id": 0,
"key": "$_id",
"value": 1,
"createdAt": "$values.createdAt",
"compared": { "$cmp": ["$value", "$values.value"] }
}
},
{
"$match": { "compared": 0 }
}
])