There is a collection
{
"field": {
"nested": 0
}
}
It is necessary to get a sum of nested fields. As direct operation like below is not allowed
{
"$group": {
"_id": null,
"field.nested": {
"$sum": "$field.nested"
}
}
}
It is done by the following aggregation with pre and post projection.
[
{
"$project": {
"fieldNested": "$field.nested"
}
},
{
"$group": {
"_id": null,
"fieldNested": {
"$sum": "$fieldNested"
}
}
},
{
"$project": {
"total": {
"field" : {
"nested" : "$fieldNested"
}
}
}
}
]
And it works correctly in the Mongo DB shell. The problem comes with using this aggregation in Spring Data in a json format. For example,
@Repository
public interface Sample extends MongoRepository<InData, String> {
@Aggregation({
"" +
"{" +
" '$project': {" +
" 'fieldNested': '$field.nested'" +
" }" +
"}",
"" +
"{" +
" '$group': {" +
" '_id': null," +
" 'fieldNested': {" +
" '$sum': '$fieldNested'" +
" }" +
" }" +
"}",
"" +
"{" +
" '$project': {" +
" 'total': {" +
" 'field': {" +
" 'nested': '$fieldNested'" +
" }" +
" }" +
" }" +
"}"
})
List<OutData> aggregateBy();
}
Somehow this json is rewritten by Spring Data so that the pipelines sent to the Mongo looks like the following
[
{
"$project": {
"field.nested": "$field.nested"
}
},
{
"$group": {
"_id": null,
"field.nested": {
"$sum": "$fieldNested"
}
}
},
{
"$project": {
"total": {
"field" : {
"nested" : "$fieldNested"
}
}
}
}
]
fieldNested
is replaced by field.nested
. As a result the aggregation fails.
Why it happens? Is there any way to avoid this rewrite by Spring Data for MongoDB (Spring Boot 2.2.13.RELEASE, MongoDB 3.6.8)?
Spring Data MongoDB is converting fieldNested
to field.nested
because your InData
class & its collection is having fields in that hierarchy. If you want to project that nested field using @Aggregation
, then project it using any other name that is not part of your InData class & its collection's fields so Spring Data won't convert it.