Spring Data MongoDb - Best way to handle mapping of the composite ID field resulting from aggregation grouping?

Viewed 231

In native MongoDb behavior, the result of an Aggregation Grouping operation is a composite document id consisting of the fields grouped on. Prior to Spring Data Mongo 3.x, the spring mapping layer would disassemble the composite id produced by grouping, and automatically map each portion of the composite id to its original field.

2.x :

Aggregation.group( FieldOne, FieldTwo, FieldThree ) --> Document { _id: null, FieldOne: X, FieldTwo: Y, FieldThree: Z } 

3.x :

Aggregation.group( FieldOne, FieldTwo, FieldThree ) --> Document { _id: [FieldOne: X, FieldTwo: Y, FieldThree: Z], FieldOne: null, FieldTwo: null, FieldThree: null }

https://jira.spring.io/browse/DATAMONGO-2437

Has anyone found an elegant way to simulate the old behavior of Spring Data MongoDb 2.x? I am working on a project with a large number of Mongo Collections and Spring Data Mongo Aggregations, and I would prefer not to heavily modify them all or write custom spring converters for each.

1 Answers

There is no "spring magic" for this. In other words, there isn't a migration config/method to make use of flatten behaviour in Spring Data MongoDB 2.x

As indicated in this Github comment: https://github.com/spring-projects/spring-data-mongodb/issues/3458#issuecomment-752678298, one needs to provide a project stage to flatten the fields manually, or introduce a corresponding composite id field in application's level

Example: (Java)

Project stage:

Aggregation.project(
Fields.from(
Fields.field("Field1", "$_id.Field1"), 
Fields.field("Field2", "$_id.Field2")
)).andExclude("_id") // optional if you want to remove composite id field in mapped results

Introduce composite id at application level:

class A {
    CompositeId id;

    class CompositeId {
        Field1 field1;
        Field2 field2;
    }
}
Related