2012-06-09 30 views
0

我有条目的这样一个集合:不同的组通过使用MongoDB的具有pymongo

db.mesh_captors.save({'arduino': 0xCB, 'pin': 14, 'value': 35, 'date': datetime.utcnow()}) 
db.mesh_captors.save({'arduino': 0xCB, 'pin': 14, 'value': 63, 'date': datetime.utcnow()}) 
db.mesh_captors.save({'arduino': 0xCB, 'pin': 15, 'value': 126, 'date': datetime.utcnow()}) 
db.mesh_captors.save({'arduino': 0x7B, 'pin': 14, 'value': 121, 'date': datetime.utcnow()}) 

我想获得一个Arduino的每个引脚的最后一个值。有了MySQL,我会写下:

SELECT DISTINCT pin, value 
FROM mesh_captors 
WHERE arduino = 203 
GROUP_BY pin 
ORDER BY date DESC 

但是使用MongoDB,我不太确定如何去做。

我尝试了这样的东西,但它足够好吗?

reducer = Code(""" 
       function (doc, out) { 
        if(out.date == 0 || out.date < doc.date) { 
         out.date = doc.date; 
         out.value = doc.value; 
        } 
       } 
       """) 

captors_value = db.mesh_captors.group(key=['pin'], condition={'arduino': int(arduino_id)}, reduce=reducer, initial={'date': 0}) 

现在,我花了超过4.5秒来执行请求,并且随着条目数量的增长,它需要越来越多的时间。

+0

。很混乱?请简化 – Rishabh

+0

好吧,我没有重新考虑我的问题 – Natim

+0

你有没有在'pin'上定义一个索引,'arduino' – Rishabh

回答

2

如果您可以使用即将发布的2.2版本的开发版本2.1版,那么您可以使用新的aggregation framework以比map/reduce更快的速度执行此查询。

这里是什么aggregation pipeline会是什么样得到适合该arguino和销最近日期的值:

[{$match:{arduino: 0xCB}}, 
{$project: 
     {_id: 0, arduino:1, pin:1, maxVal: {date:1, val:"$value"} } 
}, 
{$group: 
     {_id:{"arduino":1, "pin":1},maxDate:{$max:"$maxVal"} }  
}, 
{$project: 
     {_id:0, "arduino":"$_id.arduino" , "pin":"$_id.pin","date":"$maxDate.date",value:"$maxDate.val"} 
}] 

如果您的样本数据上运行,其结果是:

> db.mesh_captors.aggregate(agg) 
{ 
    "result" : [ 
     { 
      "arduino" : 203, 
      "pin" : 15, 
      "date" : "Sat Jun 09 2012 16:22:50 GMT-0700 (PDT)", 
      "value" : 126 
     }, 
     { 
      "arduino" : 203, 
      "pin" : 14, 
      "date" : "Sat Jun 09 2012 16:23:00 GMT-0700 (PDT)", 
      "value" : 63 
     } 
    ], 
    "ok" : 1 
} 

您可以通过对db.runCommand的pymongo支持从Python访问汇总框架。您将执行db.runCommand通过它你问那么问题标记部分为答案,然后编辑并问另外一个问题的文件

{"aggregate":"mesh_captors", "pipeline":<pipeline-goes-here>} 
0

您不能在分片集合中使用组,并且使其成为大多数任务的不好选择。如果你不使用可能接近最佳性能的分片集合,你可以得到。 (如果我错了,请纠正我)您应该尝试使用MapReduce执行相同的任务并汇总和比较性能。

This article应该可以帮助您更好地理解来自mongodb的一些高级聚合。

+0

我没有使用分片,但我认为,我必须实现一些cron作业,这将删除旧数据,所以我会保持11ms的速度。 – Natim