我有一个这样的集合:
{
_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"
}
我使用aggregate
,match
,sort
尝试了很多group
,但没有成功......
答案 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
构建动态javascript
和aggregate
阶段{1}}功能。