这是我的架构

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 }
    }
])

09-26 13:07