我正在开展一个个人项目,在这个项目中我需要通过舍入日期将所有对象分组到同一小时。问题是我不想把事情搞砸。
我在mongodb中使用以下格式存储数据
{
"_id" : ObjectId("4d663451d1e7242c4b68e000"),
"date" : "Mon Dec 27 2010 18:23:22 GMT+0000 (UTC)",
"name" : "james"
}, {
"_id" : ObjectId("4d6634514cb5cb2c4b69e000"),
"date" : "Mon Dec 27 2010 18:47:53 GMT+0000 (UTC)",
"name" : "bond",
}, {
"_id" : ObjectId("4d6634514cb5cb2c4b69e000"),
"date" : "Mon Dec 27 2010 21:51:23 GMT+0000 (UTC)",
"name" : "bruce",
}
我正在寻找以下格式的结果
{
"rounded_date" : "Mon Dec 27 2010 18:00:00 GMT+0000 (UTC)",
"items" : [ {
"_id" : ObjectId("4d663451d1e7242c4b68e000"),
"date" : "Mon Dec 27 2010 18:23:22 GMT+0000 (UTC)",
"name" : "james"
}, {
"_id" : ObjectId("4d6634514cb5cb2c4b69e000"),
"date" : "Mon Dec 27 2010 18:47:53 GMT+0000 (UTC)",
"name" : "bond",
}
]
}, {
"rounded_date": Mon Dec 27 2010 21:00:00 GMT+0000 (UTC),
"items" : [ {
"_id" : ObjectId("4d6634514cb5cb2c4b69e000"),
"date" : "Mon Dec 27 2010 21:51:23 GMT+0000 (UTC)",
"name" : "bruce",
}
]
}
谢谢你的帮助。
答案 0 :(得分:4)
这似乎是aggregation framework(mongoDB 2.2中的新功能)的一个很好的候选者,唯一需要注意的是你现在无法动态创建新日期,但是你可以从日期和时间中提取所需的数据。由它组成。
请参阅以下示例:
# Load the sample data
db.datetest.save({
"_id" : ObjectId("4d663451d1e7242c4b68e000"),
"date" : ISODate("2010-12-27T18:23:22Z"),
"name" : "james"
});
db.datetest.save({
"_id" : ObjectId("4d6634514cb5cb2c4b69e000"),
"date" : ISODate("2010-12-27T18:47:53Z"),
"name" : "bond",
});
db.datetest.save({
"_id" : ObjectId("4d6634514cb5cb2c4b69e001"),
"date" : ISODate("2010-12-27T21:51:23Z"),
"name" : "bruce",
});
现在执行聚合 - 首先将文档重新投影到有用的格式。
db.datetest.aggregate(
{$project: {
hour: {0: {"$year": "$date"},
1: {"$month": "$date"},
2: {"$dayOfMonth": "$date"},
3: {"$hour": "$date"}},
item: {
_id: "$_id",
date: "$date",
name: "$name"
}
}},
{$group: {
_id: "$hour",
items: {$push: "$item"}
}}
)
聚合解释:
hour
子文档,其中包含从日期中提取的年,月,日和小时。我们还创建了一个item
子文档,我们将在该组中使用。hour
分组,并将所有item
个文档推送到items
数组。结果如下:
{
"result" : [{
"_id" : { "0" : 2010, "1" : 12, "2" : 27, "3" : 21 },
"items" : [
{
"date" : ISODate("2010-12-27T21:51:23Z"),
"name" : "bruce"
}
]}, {
"_id" : {"0" : 2010, "1" : 12, "2" : 27, "3" : 18},
"items" : [{
"date" : ISODate("2010-12-27T18:23:22Z"),
"name" : "james"
}, {
"date" : ISODate("2010-12-27T18:47:53Z"),
"name" : "bond"
}
]}
],
"ok" : 1
}
答案 1 :(得分:0)
我找到了另一个解决方案:
db.collection.group({
cond: {'public': true},
keyf: function(doc) {
var date = doc.when
date.setMinutes(0,0,0);
return {'date' : date};
},
initial: { items:[] },
reduce: function(doc, out) { out.items.push(doc); }
});
事情是在使用groupby之后不可能对某些内容进行排序。我想我必须在客户端这样做。