Mongodb组和排序

时间:2011-07-01 11:37:16

标签: mongodb

我使用mongodb作为rails 3的数据库

如何在mongodb中为以下sql执行类似的代码。有没有办法在mongod中执行分组和排序

select a,b,sum(c) csum from coll where active=1 group by a,b order by a

由于

9 个答案:

答案 0 :(得分:16)

使用聚合框架,您可以执行以下操作:

db.coll.aggregate({ 
    $group: { 
        _id: "$a", 
        countA: { $sum: 1}, 
        sumC:{ $sum: "$c"}, 
    },
    $sort:{a:1}
});

但是,如果您有太多数据,可能会收到以下错误消息:

{
    "errmsg" : "exception: aggregation result exceeds maximum document size (16MB)",
    "code" : 16389,
    "ok" : 0
}

在此处查看有关SQL to Mongo翻译的更多信息:http://docs.mongodb.org/manual/reference/sql-aggregation-comparison/

答案 1 :(得分:16)

受到mongo网站example的启发。

生成虚假数据:

> db.stack.insert({a:1,b:1,c:1,active:1})
> db.stack.insert({a:1,b:1,c:2,active:0})
> db.stack.insert({a:1,b:2,c:3,active:1})
> db.stack.insert({a:1,b:2,c:2,active:0})
> db.stack.insert({a:2,b:1,c:3,active:1})
> db.stack.insert({a:2,b:1,c:10,active:1})
> db.stack.insert({a:2,b:2,c:10,active:0})
> db.stack.insert({a:2,b:2,c:5,active:1})

MONGO QUERY:

> db.stack.aggregate(
... {$match:{active:1}},
... {$group:{_id:{a:"$a", b:"$b"}, csum:{$sum:"$c"}}},
... {$sort:{"_id.a":1}})

结果:

{"result" : [
    {"_id" : {"a" : 1,"b" : 2},"csum" : 3},
    {"_id" : {"a" : 1,"b" : 1},"csum" : 1},
    {"_id" : {"a" : 2,"b" : 2},"csum" : 5},
    {"_id" : {"a" : 2,"b" : 1},"csum" : 13}
],"ok" : 1}

(注意:我重新格式化了shell结果,因此它更具可读性)

答案 2 :(得分:4)

我建立了一个直方图,我用2.2.2版做的是:

answer = db.coll.group(...)
db.histo.insert(answer)
db.histo.find().sort({ field: 1 })

此时,如果您不需要它,只需db.histo.drop()

您也可以避开变量并执行:

db.histo.insert(db.coll.group(...))
db.histo.ensureIndex({ field: 1 })

答案 3 :(得分:4)

mongodb聚合API似乎已经改变。现在你会做

db.coll.aggregate([
  {
     $group: { 
        _id: "$a", 
        countA: { $sum: 1}, 
        sumC:{ $sum: "$c"}, 
     }
  },
  {
    $sort:{a:1}
  }
])

注意aggregate()参数的Array语法。你还可以添加链接$ match,$ limit等作为这个数组的元素。

答案 4 :(得分:1)

答案 5 :(得分:1)

db.coll.group(
       {key: { a:true, b:true },
        cond: { active:1 },
        reduce: function(obj,prev) { prev.csum += obj.c; },
        initial: { csum: 0 }
        });

您可以在MongoDB中执行它

答案 6 :(得分:1)

您可以按照 $group > $sort 的顺序使用 $group 和 $sort 聚合。 在组之前使用排序将不起作用。 考虑以下示例:

let data = await ABCModel.aggregate([
      {
        $match: { city: { $nin: ['', null] }},
      },
      {
        $group: {
          _id: { $toLower: '$city' }
        },
      },
      { $sort: { _id: 1 } },
    ]);

答案 7 :(得分:0)

在MongoDB 2.1中发布Aggregation Framework之前,this answer中对组的调用相当慢,因为它使用的是数据库的JavaScript部分。

您可以使用更快的方法来计算组:

var res = [];
for( var cur_a = db.coll.distinct('a'); cur_a.hasNext(); ) {
  var a = cur_a.next();
  for( var cur_b = db.coll.distinct('b'); cur_b.hasNext(); ) {
    var b = cur_b.next();
    res.push({ 'a': a, 'b' : b 'count': db.coll.count({'a':a,'b':b})}
  }
}

如果您在 a b

上有索引,会更快
db.coll.ensureIndex({'a':1,'b':1})

答案 8 :(得分:0)

我想添加以下查询,例如,在两个分组的情况下,它可能很有用。

查询:

db.getCollection('orders').aggregate([
    {$match:{
        tipo: {$regex:"[A-Z]+"}
        }
    },
    {$group:
        { 
            _id:{
                codigo:"1",
                fechaAlta:{$substr:["$fechaAlta",0,10]},
            },
            total:{$sum:1}
        }
    },
    {$sort:
        {"_id":1}
    },
    {$group:
        {
            _id:"$_id.codigo",
            fechasAltas:
            {
                $push:
                {
                    fechaAlta:"$_id.fechaAlta",
                    total:"$total"
                }
            },
            totalGeneral:{$sum:"$total"}
        }
    }
]); 

响应:

{
"_id" : "1",
"fechasAltas" : [ 
    {
        "fechaAlta" : "1940-01-01",
        "total" : 13.0
    }, 
    {
        "fechaAlta" : "2007-05-14",
        "total" : 115.0
    }, 
    {
        "fechaAlta" : "2008-09-30",
        "total" : 58.0
    }, 

    .
    .
    .
],
"totalGeneral" : 50620.0
}       
相关问题