MongoDB:每个领域的最新价值

时间:2016-10-18 21:09:58

标签: mongodb group-by database

我有一个这样的集合:

{
    _id : 1,
    key : "one",
    date : ISODate("2016-10-18 08:00.000"),
    a : "a1",
    b : "b1"
},
{
    _id : 2,
    key : "two",
    date : ISODate("2016-10-18 09:00.000"),
    a : "a2",
    b : "b2"
},
{
    _id : 3,
    key : "one",
    date : ISODate("2016-10-18 10:00.000"),
    b : "b3",
    c : "c3"
},
{
    _id : 4,
    key : "one",
    date : ISODate("2016-10-18 11:00.000"),
    b : "b4"
}

我想运行一个程序,为每个字段返回其最新值(基于字段date),因此对于前一个集合,我会收到此结果:

{
    _id : "one",
    a : "a1",
    b : "b4",
    c : "c3"
},
{
    _id : "two",
    a : "a2",
    b : "b2"
}

我使用aggregatematchsort尝试了很多group,但没有成功......

1 个答案:

答案 0 :(得分:3)

您需要做的是sort文档date然后group$push这些值,因此最新值将是新文件中的第一个元素group阶段之后的数组。之后,在$project阶段,使用$arrayElemAt以显示最新值。如果数组为空(如在key: two的示例中),则不会将该值预测为预期结果。对于您的示例,它看起来像这样:

db.test.aggregate([
    {
        $sort: {
            date: -1
        }
    },
    {
        $group: {
            _id: '$key',
            a: {$push: '$a'},
            b: {$push: '$b'},
            c: {$push: '$c'}
        }
    },
    {
        $project: {
            a: {$arrayElemAt: ['$a', 0]},
            b: {$arrayElemAt: ['$b', 0]},
            c: {$arrayElemAt: ['$c', 0]}
        }
    }
])

此解决方案的唯一问题是您已知道字段名称。它不可能做一个"泛型"将在所有可用字段上执行此操作的聚合。因此,如果您知道可能的字段,那就不是问题了。如果您使用mongoose或类似内容使用它,则可以在调用{schema之前使用$group使用$project构建动态javascriptaggregate阶段{1}}功能。