如何在Spring的Date/Time(年月日时)部分写Mongodb聚合组流水线?
How to write Mongodb aggregation group pipeline on part of Date/Time(Year, month, day, hour) in Spring?
我需要帮助在 spring 中编写 mongodb 聚合管道。
这是我要对其执行查询的数据示例(请注意,以下数据是 Match 聚合管道在 spring 中的结果它有条件使 eventDate 匹配范围并且 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 聚合管道,它应该 group 在 Year、Month、Day 和 Hour 因为我要查找的是每小时数据。
我希望它看起来像哪些项目只有 eventDate 和 eventName 字段的结果示例:
{
"eventDate": ISODate("2017-01-29T03:00:00.000Z"),
"eventName": "A"
}
{
"eventDate": ISODate("2017-01-29T04:00:00.000Z"),
"eventName": "A"
}
因此,如果您注意到上面的数据是在一组小时内,除此之外,分钟和秒现在设置为 0。
我试过这个解决方案但对我不起作用:
感谢任何形式的帮助。提前致谢。
你可以在这里使用日期算法来得到日期时间,分秒毫秒部分重置为0。
您可能需要根据您的springmongo版本和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"
}
}
}]
)
Spring代码:
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代码
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);
我需要帮助在 spring 中编写 mongodb 聚合管道。
这是我要对其执行查询的数据示例(请注意,以下数据是 Match 聚合管道在 spring 中的结果它有条件使 eventDate 匹配范围并且 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 聚合管道,它应该 group 在 Year、Month、Day 和 Hour 因为我要查找的是每小时数据。
我希望它看起来像哪些项目只有 eventDate 和 eventName 字段的结果示例:
{
"eventDate": ISODate("2017-01-29T03:00:00.000Z"),
"eventName": "A"
}
{
"eventDate": ISODate("2017-01-29T04:00:00.000Z"),
"eventName": "A"
}
因此,如果您注意到上面的数据是在一组小时内,除此之外,分钟和秒现在设置为 0。
我试过这个解决方案但对我不起作用:
感谢任何形式的帮助。提前致谢。
你可以在这里使用日期算法来得到日期时间,分秒毫秒部分重置为0。
您可能需要根据您的springmongo版本和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"
}
}
}]
)
Spring代码:
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代码
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);