2011-07-01 74 views
19

我正在使用mongod作爲數據庫與rails 3Mongodb組和排序

我如何執行類似的代碼爲mongod中的以下sql。有沒有什麼辦法來執行分組和排序中的mongod

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

感謝

回答

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

您可以在MongoDB中

執行它
+5

只有基團,其中排序? – Jaro

0

直到Aggregation Framework是釋放的MongoDB 2.1,在this answer呼籲羣,是相當緩慢的,因爲它使用DB的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})} 
    } 
} 

這將是更快,如果你有一個指標b

db.coll.ensureIndex({'a':1,'b':1}) 
4

我建立了一個直方圖和我做的2.2.2版本是:

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

此時,如果你不需要它,只需。

您也可避免變量做:

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

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

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到Mongo的翻譯在這裏:http://docs.mongodb.org/manual/reference/sql-aggregation-comparison/

+0

/訂單馬呂斯,無視我的編輯,我必須有別的東西錯了,它可以作爲你寫的吧!對不起! – SteveO7

+3

這不工作「管道階段規範對象必須只包含一個字段。」 – user3690202

14

受mongo網站上此example的啓發。

GENERATE僞數據:

> 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} 

(注:我重新格式化所述殼導致了一點,所以它更可讀的)

4

mongodb agg法規API似乎發生了變化。現在你可以做

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

注意參數aggregate()的數組語法。你還可以添加鏈接$匹配,$限制等作爲這個數組的元素。