我在用Mongodb。考虑我的下一份文件:
{ uid: 1, created: ISODate("2014-05-02..."), another_col : "x" },
{ uid: 1, created: ISODate("2014-05-05..."), another_col : "y" },
{ uid: 2, created: ISODate("2014-05-10..."), another_col : "z" },
{ uid: 3, created: ISODate("2014-05-05..."), another_col : "w" },
{ uid: 1, created: ISODate("2014-05-01..."), another_col : "f" },
{ uid: 2, created: ISODate("2014-05-22..."), another_col : "a" }我要做的是在uid上创建一个简单的groupby,并按降序排序创建的,这样我就可以得到每个uid的第一行。
预期输出的示例
{ uid: 1, created: ISODate("2014-05-05..."), another_col: "y" },
{ uid: 2, created: ISODate("2014-05-22..."), another_col: "a" },
{ uid: 3, created: ISODate("2014-05-05..."), another_col: "w" }我能得到的最好结果是:
db.mycollection.aggregate( {$group: {_id: "$uid", rows: {$push: { "created" : "$created" }}}}, sort { // doesnt work well } )有谁能引导我通过分组和排序来正确组合?只是不像我预料的那样起作用了。(注:我检查过许多线程,但无法找到正确的答案)
发布于 2014-05-30 07:43:22
这里有几个陷阱需要理解。
当您使用$group时,边界将按照在没有初始或结束阶段$sort操作的情况下被发现的顺序排序。因此,如果您的文档最初是按如下顺序排列的:
{ uid: 1, created: ISODate("2014-05-02..."), another_col : "x" },
{ uid: 1, created: ISODate("2014-05-05..."), another_col : "y" },
{ uid: 3, created: ISODate("2014-05-05..."), another_col : "w" },
{ uid: 2, created: ISODate("2014-05-10..."), another_col : "z" },然后,只要在管道的末尾使用没有$sort的$sort,就会返回如下结果:
{ uid: 1, created: ISODate("2014-05-05..."), another_col : "y" },
{ uid: 3, created: ISODate("2014-05-05..."), another_col : "w" },
{ uid: 2, created: ISODate("2014-05-10..."), another_col : "z" },这是一个概念,但实际上,您在结果中所期望的似乎需要按照uid的排序顺序返回“最后一个其他字段”,这就是您要寻找的。在这种情况下,获得结果的方法实际上是首先使用$sort,然后使用$last操作符:
db.mycollection.aggregate([
// Sorts everything first by _id and created
{ "$sort": { "_id": 1, "created": 1 } },
// Group with the $last results from each boundary
{ "$group": {
"_id": "$uid",
"created": { "$last": "$created" },
"another_col": { "$last": "$created" }
}}
])或者从本质上对你想要的东西应用这种方法。
$last和$max的不同之处在于,后者将为分组_id中的给定字段选择“最高”值,而不管在未排序的顺序上当前排序如何。另一方面,$last将选择与“最后”分组_id值相同的“行”中的值。
如果您实际上是想对数组的值进行排序,那么这种方法是相似的。保持数组成员的“创建”顺序,您也可以先排序:
db.mycollection.aggregate([
// Sorts everything first by _id and created
{ "$sort": { "_id": 1, "created": 1 } },
// Group with the $last results from each boundary
{ "$group": {
"_id": "$uid",
"row": {
"$push": {
"created": "$created",
"another_col": "$another_col"
}
}
}}
])带有这些字段的文档将按照已经被排序的顺序添加到数组中。
发布于 2014-05-27 21:49:49
如果你要找的只是第一行,那就意味着你在寻找最大的。只需使用内置$max累加器即可。
db.mycollection.aggregate([{$group: {_id: "$uid", rows: {$max:"$created"}}}])如果需要处理所有创建日期,可以使用$push累加器。有关累加器的更多信息,请参见:http://docs.mongodb.org/manual/reference/operator/aggregation/group/
如果您想要返回完整的文档,并且希望能够迭代所有文档,那么就不需要聚合结果了。像这样的东西应该能让你得到你想要的。
db.mycollection.find({$query:{}, $orderby:{uid:1,created:-1}})发布于 2014-05-28 11:25:41
在使用$project的同时
db.mycollection.aggregate([{$group: {_id: "$uid", rows: {$max:"$created"}}}])应该对你有帮助,请参考以下链接
http://docs.mongodb.org/manual/reference/operator/aggregation/project/
https://stackoverflow.com/questions/23899409
复制相似问题