0

我有一个这样的条目集合:

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 秒,并且随着条目数量的增加,需要的时间也越来越多。

4

2 回答 2

2

如果您可以使用即将发布的 2.2 版本的开发版本 2.1,那么您可以使用新的聚合框架来比使用 map/reduce 更快地执行此查询。

以下是聚合管道获取该 arguino 和 pin 的最新日期值的样子:

[{$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 支持从 Python 访问聚合框架db.runCommand。您将执行db.runCommand将文件传递给它

{"aggregate":"mesh_captors", "pipeline":<pipeline-goes-here>}
于 2012-06-09T23:51:03.617 回答
0

您不能在分片集合中使用组,这对于大多数任务来说是个糟糕的选择。如果您不使用可能接近您可以获得的最佳性能的分片集合。(如果我错了,请纠正我)您应该尝试使用 MapReduce 实现相同的任务并汇总和比较性能。

这篇文章应该可以帮助你更好地理解来自 mongodb 的一些高级聚合。

于 2012-06-09T13:23:23.807 回答