Senthil Arumugam SP
Senthil Arumugam SP

Reputation: 1529

Spring Data MongoDB - Aggregate Method

Do anyone know how to convert the below aggregation function into a java code using Spring-data?

db.myCollection.aggregate([
    {$match:{"status" : {$in:["WORKING","UNASSIGNED"]}}},
    {$group:{
            _id:{
                "status":"$status",
                "queue":"$queueName"
             },
             "count":{$sum:1},
             "oldest":{$min:"$queueTime"},
             "slow":{$sum:{$cond:[
                                {$lte: ["$queueServiceTs", new Date()]},
                                        1,
                                        0]}
                          }

        }
    }
]);

Upvotes: 4

Views: 1707

Answers (1)

Blakes Seven
Blakes Seven

Reputation: 50416

Spring mongo does not currently support either:

  1. A composite aggregation _id with custom key names, though of course you could just accept the defualt field name translation

  2. Usage of the $cond operation or any expression within a $sum, as it just supports a mapped field only.

So the second there is the thing that breaks usage of the aggregation helper functions in this case. You could work around that by doing a $project first, but that requires an additional stage of execution that will affect the performance.

But what you can do is create your own abstract class that works within the standard builder functions but allows you to build the pipeline stage with standard objects:

public class CustomGroupOperation implements AggregationOperation {
    private DBObject operation;

    public CustomGroupOperation (DBObject operation) {
        this.operation = operation;
    }

    @Override
    public DBObject toDBObject(AggregationOperationContext context) {
        return context.getMappedObject(operation);
    }
}

And then you can use it with the standard builder as follows:

    Aggregation aggregation = newAggregation(
            new CustomGroupOperation(
                    new BasicDBObject("$group",
                        new BasicDBObject("_id",
                            new BasicDBObject("status","$status")
                                .append("queue","$queueName")
                        )
                        .append("count",new BasicDBObject("$sum",1))
                        .append("oldest", new BasicDBObject("$min","$queueTime"))
                        .append("slow",
                            new BasicDBObject("$sum",
                                new BasicDBObject("$cond",Arrays.asList(
                                    new BasicDBObject("$lte",Arrays.asList(
                                        "$queueServiceTs",
                                        new Date()
                                    )),
                                    1,
                                    0
                                ))
                            )
                        )
                    )
            )
    );

And that builds a pipeline with the $group stage exactly as you have it defined.

Upvotes: 6

Related Questions