下面是我的代码。我想找到满足聚合方法中的条件的所有行。当聚合返回对象数组时,我想找到符合这个条件的行。我希望按排序顺序排列数据。我必须使用mongodb的排序方法而不是节点js。
train.aggregate([
{$group :
_id :'$trainNo',
total : {$max : '$distance' }
trainName : {'$first' : '$trainName'}
}
]).sort({total : 1}).forEach(function(docs) {
// train.find( {'distance' : docs.total, 'trainNo' : docs._id}, {trainNo : 1, trainName : 1, distance : 1}).toArray(function (err,data) {
// finalResult.push(data);
// })
console.log(docs);
});
答案 0 :(得分:0)
不要在 $max
步骤中使用 $group
运算符,而是使用 $first
运算符这样您就可以使用要返回的字段扩展聚合 $group
管道步骤。当您在分组阶段之前对初始管道文档进行排序时,这种方法效果最佳。
最终的 $sort
管道阶段将用于订购您生成的文档。以下显示了如何解决此问题:
var pipeline = [
{ "$sort": { "distance": -1 } },
{
"$group": {
"_id": "$trainNo",
"total": { "$first": "$distance" },
"trainName": { "$first": "$trainName" },
"distance": { "$first": "$distance" },
"id": { "$first": "$_id" }
}
},
{
"$project": {
"_id": "$id",
"trainNo": "$_id",
"total": 1,
"trainName": 1,
"distance": 1
}
},
{ "$sort": { "total": -1 } }
]
train.aggregate(pipeline, function(err, r){
console.log(r);
})
在上面的管道中,第一步是 $sort
运算符,它类似于SQL的ORDER BY
子句。要按降序对特定字段进行排序,请指定-1,如果该字段必须按升序排序,则指定1。
在您的情况下,它会根据distance
字段进行排序。这是下一个管道阶段的必要操作, $group
步骤,您需要通过获取第一个/顶部的值来获取每个分组文档的最大distance
订购分组文件时的文件。
这里需要注意的一点是,在执行管道时,MongoDB会将运营商相互管道化。 "管"这里采用Linux的含义:运算符的输出成为以下运算符的输入。每个运算符的结果是一个新的文档集合。所以Mongo按如下方式执行上一个管道:
collection | $sort | $group | $project | $sort => result
在 $group
管道中,您现在按trainNo
字段对已排序的文档进行分组,然后使用累加器在分组的文档上返回所需的聚合。累加器运算符 $first
在此分组操作中是理想的,因为当文档按照定义的顺序时,它会从每个组的第一个文档返回一个值,在这种情况下,您按顺序排序距离下降。
$group
阶段中使用的累加器会在文档进入管道时保持其状态(例如总数,最大值,最小值和相关数据)。
要获取包含所需字段的文档,使用与SQL中的SELECT
类似的 $project
运算符来重命名字段名称并选择/取消选择字段从分组的字段中返回。如果为字段指定0,则不会在管道中将其发送到下一个运算符。
最后 $sort
管道步骤然后重新排序所需密钥上的文档。