我想在mongoDB中使用组聚合,以便根据文档的创建日期对文档进行分组。我没有将创建日期保存为一个字段,但我知道我可以从我的ObjectId中提取这个日期。所以,我试着这样写:
db.sales.aggregate(
[
{
$group : {
_id : { month: {$month: ObjectId("$_id").getTimestamp()},
day: {$dayOfMonth: ObjectId("$_id").getTimestamp()},
year: {$year: ObjectId("$_id").getTimestamp()}
},
averageQuantity: { $avg: "$quantity" },
count: { $sum: 1 }
}
}
]
)
我得到这个错误:错误:无效的对象id:长度:@(壳):37
它工作,当我写一个特殊的ObjectId而不是"$_id"。例如:ObjectId("507"c7f79bcf86cd7994f6c0e) .getTimestamp ()
它也可以工作,当我有一个日期字段,我在其中存储了我的创建日期,然后像这样写:
db.sales.aggregate(
[
{
$group : {
_id : { month: {$month: "$date"},
day: {$dayOfMonth: "$date"},
year: {$year: "$date"}
},
averageQuantity: { $avg: "$quantity" },
count: { $sum: 1 }
}
}
]
)
但是我想知道,我如何直接使用我的ObjectId并获取时间戳。
在此链接中可以找到聚合组及其相关数据:https://docs.mongodb.com/manual/reference/operator/aggregation/group/
但是我用mongoDB自动生成的id s替换了这个例子中的简单整数id s。
getTimestamp()是一个函数,它应该在javascript函数中使用。
您需要在查询中更正两件事。一个是获取Id,另一个是使用getTimestamp()函数。
Id的检索
_id : { month: {$month: ObjectId("$_id").getTimestamp()},
day: {$dayOfMonth: ObjectId("$_id").getTimestamp()},
year: {$year: ObjectId("$_id").getTimestamp()}
}
用月、日、年检索id的正确方法
_id : { month: "$_id.month", day: "$_id.day", year: "$_id.year"},
原因:
month是文档id的一部分,因此必须以这种方式检索。日期和年份也一样。
获取时间戳
将结果放入javascript循环并使用getTimestamp()方法。
db.sales.aggregate(
[
{
$group : {
_id : { month: "$_id.month", day: "$_id.day", year: "$_id.year"},
averageQuantity: { $avg: "$quantity" },
count: { $sum: 1 }
}
}
]
).forEach(function (doc)
{
doc["doc._id.month"]=doc._id.month.getTimestamp();
doc["doc._id.day"]=doc._id.day.getTimestamp();
doc["doc._id.year"]=doc._id.year.getTimestamp();
printjson(doc);
});
如果你有一个像这样的集合
{
"_id" : {
"month" : ObjectId("57bd7d3c0da65e3f92328e50"),
"day" : ObjectId("57bd7d3c0da65e3f92328e51"),
"year" : ObjectId("57bd7d3c0da65e3f92328e52")
},
"quantity" : 200
}
和使用javascript函数执行聚合查询后的结果将给出以下结果
{
"_id" : {
"month" : ObjectId("57bd7d3c0da65e3f92328e50"),
"day" : ObjectId("57bd7d3c0da65e3f92328e51"),
"year" : ObjectId("57bd7d3c0da65e3f92328e52")
},
"averageQuantity" : 200,
"count" : 1,
"doc._id.month" : ISODate("2016-08-24T10:55:56Z"),
"doc._id.day" : ISODate("2016-08-24T10:55:56Z"),
"doc._id.year" : ISODate("2016-08-24T10:55:56Z")
}