我有这样的条目集合:
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 :(得分:2)
如果您可以使用版本2.1(即将发布的2.2版本的开发版本),那么您可以使用新的aggregation framework以比使用map / reduce更快的速度执行此查询。
以下是aggregation pipeline看起来像是获得该争论和销的最新日期的值:
[{$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
}
您可以通过pymongo对db.runCommand
的支持从Python访问聚合框架。您将执行db.runCommand
传递文档
{"aggregate":"mesh_captors", "pipeline":<pipeline-goes-here>}
答案 1 :(得分:0)
您不能在分片集合中使用组,这使得它成为大多数任务的不良选择。如果您没有使用可能接近最佳性能的分片集合,则可以获得。 (如果我错了,请纠正我)你应该尝试使用MapReduce实现相同的任务并聚合和比较性能。
This article应该可以帮助您更好地了解mongodb的一些高级聚合。