I have a set of mongodb documents like these
* 1 */
{
"_id" : ObjectId("613b21fe2e57a07bbacc18da"),
"date" : ISODate("2021-07-31T22:00:00.000Z"),
"initiativeId" : "613b17332e57a07bbacc164d",
"studentClass" : "3A",
"instituteId" : "60c89b7c1442725ff813733c",
"values" : [
{
"mode" : "piedi",
"distanceKm" : 12.2,
"studentNumber" : 4
},
{
"mode" : "pedibus",
"distanceKm" : 4.2,
"studentNumber" : 2
}
]
}
/* 2 */
{
"_id" : ObjectId("613b21fe2e57a07bbacc18dc"),
"date" : ISODate("2021-09-06T22:00:00.000Z"),
"initiativeId" : "613b17332e57a07bbacc164d",
"studentClass" : "5C",
"instituteId" : "60c89b7c1442725ff813733c",
"values" : [
{
"mode" : "moto",
"distanceKm" : 10.0,
"studentNumber" : 1
}
]
}
I'm using MongoDB 4.4.
I want to reproduce following working mongodb query using Spring Data Mongo (v2.2.5)
db.initiativeRecord.aggregate([
{ $addFields: { month: { year: {$year : "$date"},
month: {$month : { date: "$date", timezone: "Europe/Rome"}}
} } },
{ $unwind : "$values" },
{ $group : { _id: {d: "$month", mode: "$values.mode"}, distance: {$sum: "$values.distanceKm" } } }
])
This is the Spring data mongo code
List<AggregationOperation> operations = new ArrayList<>();
operations.add(Aggregation.unwind("values"));
ProjectionOperation subProject = Aggregation.project("values")
.and(DateOperators.Month.monthOf("date").withTimezone(Timezone.valueOf("Europe/Rome"))).as("month")
.and(DateOperators.Year.year("$date")).as("year");
operations.add(subProject);
GroupOperation group = Aggregation.group("distance","year", "month","values.mode").sum("values.distanceKm").as("distance");
project = project.andExpression("_id.mode").as("mode")
.andExpression("_id.month").as("month")
.andExpression("_id.year").as("year");
operations.add(group);
operations.add(project);
The problem is the use of timezone attribute in $month function
when I try to add this
DateOperators.Month.monthOf("date").withTimezone(Timezone.valueOf("Europe/Rome"))
execution throws following exception
Command failed with error 16006 (Location16006): 'can't convert from BSON type object to Date' on server localhost:40393. The full response is {"ok": 0.0, "errmsg": "can't convert from BSON type object to Date", "code": 16006, "codeName": "Location16006"}
When I remove withTimezone part
DateOperators.Month.monthOf("date")
execution doesn't throw the exception
I don't understand how to use withTimezone correctly in my code
After a lot of tests I can answer the question myself. I decided to do it as future documentation for everybody.
The code is correct and works well with MongoDb 4.4.
Spring data mongodb 2.2.5 supports DateOperators.Month.month.withTimeZone
correctly.
The exception was thrown by de.flapdoodle.embed.mongo
(version 2.2.0 in my case) (an embedded mongo db) I use for tests.