我需要帮助在春天编写mongodb聚合管道。
以下是我想要执行查询的数据示例(请注意,以下数据是春天匹配聚合管道的结果,其中有条件让eventDate与之匹配range和eventName等于' A'):
{
"_id": ObjectId("1234567890"),
"eventDate": ISODate("2017-01-29T03:56:04.297Z"),
"eventName": "A"
}
{
"_id": ObjectId("1234567890"),
"eventDate": ISODate("2017-01-29T03:57:04.887Z"),
"eventName": "A"
}
{
"_id": ObjectId("1234567890"),
"eventDate": ISODate("2017-01-29T04:05:00.497Z"),
"eventName": "A"
}
现在我想在eventDate字段上编写 Group 聚合管道,在年,月 分组 >,日和小时,因为我要查找的是每小时数据。
结果示例我希望它看起来像只调度eventDate和eventName字段:
{
"eventDate": ISODate("2017-01-29T03:00:00.000Z"),
"eventName": "A"
}
{
"eventDate": ISODate("2017-01-29T04:00:00.000Z"),
"eventName": "A"
}
因此,如果您注意到上面的数据是在一小时内的一小时内,那么分钟和秒数现在都设置为0.
我试过这个解决方案,但对我不起作用: MongoTemplate aggregate - group by date
任何形式的帮助表示赞赏。提前谢谢。
答案 0 :(得分:0)
您可以在此处使用日期算法将日期时间,分钟,秒和毫秒部分重置为0。
您可能需要根据spring mongo版本和java版本进行一些调整。
版本:Mongo 3.2,Spring Mongo 1.9.5版本和Java 8
Mongo Shell查询:
db.collection.aggregate(
[{
$group: {
_id: {
$subtract: ["$eventDate", {
$add: [{
$multiply: [{
$minute: "$eventDate"
}, 60000]
}, {
$multiply: [{
$second: "$eventDate"
}, 1000]
}, {
$millisecond: "$eventDate"
}]
}]
},
eventName: {
$addToSet: "$eventName"
}
}
}]
)
春季代码:
AggregationOperation group = context -> context.getMappedObject(new BasicDBObject(
"$group", new BasicDBObject(
"_id",
new BasicDBObject(
"$subtract",
new Object[]{
"$eventDate",
new BasicDBObject("$add",
new Object[]{
new BasicDBObject("$multiply",
new Object[]{new BasicDBObject("$minute", "$eventDate"), 60000}),
new BasicDBObject("$multiply",
new Object[]{new BasicDBObject("$second", "$eventDate"), 1000}),
new BasicDBObject("$millisecond", "$eventDate")
}
)
}
)
).append("eventName", new BasicDBObject("$addToSet", "$eventName"))));
更新:使用$ project
db.collection.aggregate(
[{
$project: {
eventDate: {
$subtract: ["$eventDate", {
$add: [{
$multiply: [{
$minute: "$eventDate"
}, 60000]
}, {
$multiply: [{
$second: "$eventDate"
}, 1000]
}, {
$millisecond: "$eventDate"
}]
}]
},
eventName: 1
}
}, {
$group: {
_id: "$eventDate",
eventName: {
$addToSet: "$eventName"
}
}
}]
)
Spring Code
AggregationOperation project = context -> context.getMappedObject(new BasicDBObject(
"$project", new BasicDBObject(
"eventDate",
new BasicDBObject(
"$subtract",
new Object[]{
"$eventDate",
new BasicDBObject("$add",
new Object[]{
new BasicDBObject("$multiply",
new Object[]{new BasicDBObject("$minute", "$eventDate"), 60000}),
new BasicDBObject("$multiply",
new Object[]{new BasicDBObject("$second", "$eventDate"), 1000}),
new BasicDBObject("$millisecond", "$eventDate")
}
)
}
)
).append("eventName", 1)));
AggregationOperation group = Aggregation.group("eventDate").addToSet("eventName").as("eventName");
Aggregation agg = Aggregation.newAggregation(project, group);