ongoDB Query Unwind issue

I have a mongoDB Query that uses aggregation. I am applying projection and then unwind.

 ProjectionOperation projectionPreUnwind = Aggregation.project(Fields.from(Fields.field("result.detections.reference.control", "result.detections.reference.control")));

        UnwindOperation unwindOpn = Aggregation.unwind("result.detections");

        Aggregation aggregation = Aggregation.newAggregation(projectionPreUnwind, unwindOpn);

        LOGGER.info(" aggregation {}", aggregation);

        AggregationResults<String> detectionsDataAggr = mongoTemplate.aggregate(aggregation, CASES_COLLECTION, String.class);

The code result in Error

2024-10-23 16:48:03.158 ERROR B33543D — [nio-8082-exec-9] o.a.c.c.C.[.[.[.[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: Invalid reference ‘result.detections’!] with root cause java.lang.IllegalArgumentException: Invalid reference ‘result.detections’! at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:114) at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:77) at org.springframework.data.mongodb.core.aggregation.UnwindOperation.toDocument(UnwindOperation.java:95)

Sample JSON File

{
"result": {
    "aiModel": "",
    "detections": [
        {
            "aiStatus": "PASS",
            "reference": {
                "attribute": "TEST",
                "control": "C Test"
            }
        },
        {
            "aiStatus": "FAIL",
            "reference": {
                "attribute": "TES22T",
                "control": "C Test"
            }
        }
    ]
}
```}
1 Like

Welcome @sohrab_shaikh :wave:

I think you need to make sure result.detections is included in the projection stage to make it accessible in the $unwind stage.

ProjectionOperation projectionPreUnwind = Aggregation.project()
    .and("result.detections").as("detections");

The other thing is on your $unwind.

Now, use $unwind on detections (as it’s directly projected).

UnwindOperation unwindOpn = Aggregation.unwind("detections");

Hope this helps.