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


你可能感兴趣的:(Mongodb聚合实践(一))