Mongodb聚合實踐(一)

Mongodb聚合實踐(一)

統計某段時間內相同語言的字符串總數和:
db.TranslateTicket.aggregate([{ $match : {EntityTypeName : 'Product', CreateTime:{$gt: ISODate("2014-04-10"), $lte: ISODate("2014-05-01")} } }, { $group :{ _id : "$TargetLanguage", totalCount : { $sum : "$CharactersCount" } } }])
統計運行10分鐘多,效率極其低下,尋找解決方案。

分析查詢階段
db.TranslateTicket.find({EntityTypeName : 'Product', CreateTime:{$gt: ISODate("2014-04-10"), $lte: ISODate("2014-05-01")}}).count()    => 1181579
db.TranslateTicket.find({EntityTypeName : 'Product', CreateTime:{$gt: ISODate("2014-04-10"), $lte: ISODate("2014-05-01")}}).explain
,查詢階段會返回一個包含數目爲1181579的巨大遊標,查詢階段耗費6分鐘左右。
由於原collection擁有2248338條記錄,返回結果大於一半,不適合用索引進行查詢,若是原來擁有名稱相似EntityTypeName_1_CreateTime_1這樣的索引,須要在查詢時強制數據庫作全表掃描:
db.TranslateTicket.find({EntityTypeName : 'Product', CreateTime:{$gt: ISODate("2014-04-10"), $lte: ISODate("2014-05-01")}}).hinit({"$natural : 1")
使用$natual有一個反作用,返回的結果是按照磁盤上的順序排列的,對於一個活躍的集合,隨着文檔的變化,會在磁盤上移動,若是是隻須要插入的文檔,就會很是有意義了。
解決方案:將目標數據插入到一個新的集合中:
var myCur = db.TranslateTicket.find({EntityTypeName : 'Product', CreateTime:{$gt: ISODate("2014-04-10"), $lte: ISODate("2014-05-01")}})
var docu = myCur.hasNext()? myCur.next() : null;
db.t2.insert(docu)
由於本實例中,須要對document中的字段CharactersCount進行累加,全部不可避免的形成效率很低,經分析只能採用分片的方式,將數據分而治之來獲取結果。

附:數據庫文件大小的查看命令
db.collection.dataSize()
數據文件的大小
db.collection.storageSize()
已分配數據文件的大小,包括未使用的
db.collection.totalSize()
數據文件加索引文件的大小
db.collection.totalIndexSize()
索引文件的大小        
每一個庫的具體統計信息
db._adminCommand("listDatabases").databases.forEach(function (d) {mdb = db.getSiblingDB(d.name); printjson(mdb.stats())})
每一個庫的每一個表的具體統計信息
db._adminCommand("listDatabases").databases.forEach(function (d) {mdb = db.getSiblingDB(d.name); mdb.getCollectionNames().forEach(function(c) {s = mdb[c].stats(); printjson(s)})})
數據庫

相關文章
相關標籤/搜索