最近在阅读《MongoDB权威指南》,http://book.douban.com/subject/6068947/,在看到聚合这一章的group部分时,范例程序在我的机器上运行的结果为空,因此我稍微研究了一下。
这本书上的MongoDB版本是1.6.0,我自己的机器是Ubuntu 12.04 x64,MongoDB版本是2.0.4。
下面是书上的测试数据:
db.stocks.insert({"day": "2010/10/03", "time": "2010/10/03 03:47:01 GMT-400", "price": 4.23});
db.stocks.insert({"day": "2010/10/04", "time": "2010/10/04 11:28:39 GMT-400", "price": 4.27});
db.stocks.insert({"day": "2010/10/03", "time": "2010/10/03 05:00:23 GMT-400", "price": 4.10});
db.stocks.insert({"day": "2010/10/06", "time": "2010/10/06 05:27:58 GMT-400", "price": 4.30});
db.stocks.insert({"day": "2010/10/04", "time": "2010/10/04 08:34:50 GMT-400", "price": 4.01});
书上关于group用法的程序代码:
db.runCommand({"group": {
"ns": "stocks",
"key": "day",
"initial": {"time": 0},
"$reduce": function(doc, prev) {
if (doc.time > prev.time) {
prev.price = doc.price;
prev.time = doc.time;
}
}
}});
返回结果:
{
"retval" : [
{
"time" : 0
}
],
"count" : 5,
"keys" : 1,
"ok" : 1
}
我修改后的代码:
db.runCommand({"group": {
"ns": "stocks",
"key": {"day": true},
"initial": {"time": "0"},
"$reduce": function(doc, prev) {
if (doc.time > prev.time) {
prev.price = doc.price;
prev.time = doc.time;
}
}
}});
返回结果:
{
"retval" : [
{
"day" : "2010/10/03",
"time" : "2010/10/03 05:00:23 GMT-400",
"price" : 4.1
},
{
"day" : "2010/10/04",
"time" : "2010/10/04 11:28:39 GMT-400",
"price" : 4.27
},
{
"day" : "2010/10/06",
"time" : "2010/10/06 05:27:58 GMT-400",
"price" : 4.3
}
],
"count" : 5,
"keys" : 3,
"ok" : 1
}
这里发生错误的关键在于“key”的值不能是字符串,而必须是一个对象;而“initial”的“time”应该是字符串而不能是整数。
如果不需要这么详细的返回结果的话,只需要用集合的group方法即可:
db.stocks.group({
"key": {"day": true},
"initial": {"time": "0"},
"reduce": function(doc, prev) {
if (doc.time > prev.time) {
prev.price = doc.price;
prev.time = doc.time;
}
},
"condition": {"day": {"$gte": "2009/12/31"}}
});
返回结果:
[
{
"day" : "2010/10/03",
"time" : "2010/10/03 05:00:23 GMT-400",
"price" : 4.1
},
{
"day" : "2010/10/04",
"time" : "2010/10/04 11:28:39 GMT-400",
"price" : 4.27
},
{
"day" : "2010/10/06",
"time" : "2010/10/06 05:27:58 GMT-400",
"price" : 4.3
}
]