我有一个集合,其中多个文档可能具有相同的userId
字段。我想将userId
分组,以便获得唯一userId
的列表,但也按date
排序,以便每个返回的文档都是userId
的最新文档}。我用sql完成了这样的查询,我真的希望mongo可以实现。
在此示例集合中:
{ userId: 456, date: 5/16/1988 },
{ userId: 456, date: 5/17/1988 },
{ userId: 789, date: 5/18/1988 },
{ userId: 789, date: 5/17/1988 }
我想回复:
{ userId: 456, date: 5/17/1988 },
{ userId: 789, date: 5/18/1988 }
答案 0 :(得分:2)
以下是如何在mongo中执行此操作。请注意,它使用日期格式yyyy-mm-dd。
db.collection.aggregate({
$group: {
id : '$userId',
date: { $max: '$date'}
}
})
答案 1 :(得分:0)
在你的问题中,你说你想要返回完整的文件。您可以将完整文档作为$group
运算符中的字段返回。
db.coll.aggregate([
{$sort:{date:-1}},
{$group: {_id: "$userId", doc:{$first: "$$CURRENT"}} }
])
我在Date类型的问题中创建了四个文档作为一些随机日期。这会给你以下结果:
{
"_id" : 789,
"doc" : {
"_id" : ObjectId("53d80e246ebc37d0c33321ba"),
"userId" : 789,
"date" : ISODate("2014-07-05T04:00:00.000Z")
}
},
{
"_id" : 456,
"doc" : {
"_id" : ObjectId("53d80e246ebc37d0c33321b8"),
"userId" : 456,
"date" : ISODate("2014-07-05T04:00:00.000Z")
}
}
有关$$CURENT
答案 2 :(得分:0)
虽然它们可能是正确的方法,但我无法使用db.collection.aggregate方法,因为在这种情况下我需要在Model.find上使用其他东西,如.populate()。所以我提出了一个解决方法,我在find(选项)中对userID和date进行排序,如下所示:
{ sort: { updateDate: -1, userId: -1 } }
然后我在前端编写了一个函数来为每个用户提取最新记录:
filterLatest: function(docs) {
var lastUserId = null;
var latestDocs = [];
docs.forEach(function(doc) {
if(lastUserId != doc.userId) latestDocs.push(doc);
lastUserId = doc.userId;
});
return latestDocs;
}