不同的组通过使用mongodb与pymongo

时间:2012-06-09 12:18:12

标签: mongodb group-by 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秒来执行请求,并且随着条目数量的增加需要越来越多的时间。

2 个答案:

答案 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的一些高级聚合。