【问题标题】:Sort and Group in one MongoDB aggregation query在一个 MongoDB 聚合查询中进行排序和分组
【发布时间】:2015-05-30 11:58:34
【问题描述】:

在一个聚合查询中使用 $sort$group,行为异常。

测试数据:

db.createCollection("test");

db.test.insert({
    ts : 100,
    category : 1
});

db.test.insert({
    ts : 80,
    category : 1
});

db.test.insert({
    ts : 60,
    category : 2
});

db.test.insert({
    ts : 40,
    category : 3
});

因此,当按ts 对其进行排序时,一切看起来都不错,但是当我同时使用$sort$group 时,结果顺序错误。查询:

db.test.aggregate([
{
    $sort : {ts: 1}
},
{
    $group:{"_id":"$category"}
}
]);

结果倒序:

{ "_id" : 1 }
{ "_id" : 2 }
{ "_id" : 3 }

是 Mongo 的功能还是我的误解? Maby mongo首先应用分组,然后不能按缺席字段排序。出于这个原因,mongoose 可能禁止在排序中使用 distinct。

【问题讨论】:

  • 我认为如果您先将聚合重新排列为 $group 然后 $sort 那么它可以正常工作 db.test.aggregate([ { $group:{"_id":"$category"} },{ $sort : {ts: 1} } ]);

标签: mongodb sorting mongoose mongodb-query aggregation-framework


【解决方案1】:

您需要先得到$group$sort 的结果。由于您只需要 _id 字段,因此您将需要 $project 阶段。

db.test.aggregate(
    [
        { "$group": { "_id": "$category" }},
        { "$sort" : { "ts": 1 }},
        { "$project": { "_id": 1 }}
    ]
);

【讨论】:

  • 你能告诉我一件事,当我在 $lookup 之前应用排序然后查找是否更改顺序??
【解决方案2】:

如果您想以其他方式排序,请这样做:

db.test.aggregate([
{
    $sort : {ts: -1}
},
{
    $group:{"_id":"$category"}
}
]);

注意 1 前面的 -

【讨论】:

    【解决方案3】:

    当您首先通过ts $sort 时,您基本上是在对集合中的所有元素进行排序。因此,如果您只在聚合管道中运行$sort 阶段,您将得到以下结果:

    //Query
    db.test.aggregate([
        { $sort: { ts: 1} }
    ]);
    
    //Output
    { "_id" : ObjectId("55141da6e4c260ae9e00832b"), "ts" : 40, "category" : 3 }
    { "_id" : ObjectId("55141d9fe4c260ae9e00832a"), "ts" : 60, "category" : 2 }
    { "_id" : ObjectId("55141d99e4c260ae9e008329"), "ts" : 80, "category" : 1 }
    { "_id" : ObjectId("55141d93e4c260ae9e008328"), "ts" : 100, "category" : 1 }
    

    在您的代码中,当您添加$group 阶段时,您基本上是按category 字段对上述结果进行分组,产生您得到的输出:

    { "_id" : 1 }
    { "_id" : 2 }
    { "_id" : 3 }
    

    最终,这一切都取决于您要达到的目标。

    如果要返回由ts 字段过滤的类别,则应仅使用$sort 阶段,然后操作生成的数据集:

    var data = db.test.aggregate([
                        {$sort: { ts: 1}}, 
                        {$project: { 
                            _id: 0, 
                            ts: 1, 
                            category: 1
                            }
                        }
    ]).toArray();
    
    for(var i = 0; i < data.length; i++) {
        console.log(data[i].category); //Output 3, 2, 1 in that sequence, on different lines
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-19
      • 2014-07-26
      相关资源
      最近更新 更多