I'd like to know how to implement a Standard Deviation aggregation Function to use in Spring Mongo Data.
I Know Mongo DB 3.2 has a Standard Deviation aggregation function, but It isn't available in Spring Data.
Could I use the Mongo's aggregation function?
Thanks.
There is a distinct difference between "not available" and "no implemented helper method", and that is the real case here. Just because there is no "helper" for implementing the $stdDevSamp
or $stdDevPop
operators, does not mean they cannot be used, as long as you are connecting to a MongoDB 3.2 instance of course.
All you really need is a custom class supporting the AggregationOperation
interface, that will allow construction using DBObject
:
public class CustomAggregationOperation implements AggregationOperation {
private DBObject operation;
public CustomAggregationOperation (DBObject operation) {
this.operation = operation;
}
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return context.getMappedObject(operation);
}
}
Then you can use that class in aggregation pipeline construction like so:
Aggregation aggregation = newAggregation(
new CustomAggregationOperation(
new BasicDBObject("$sample", new BasicDBObject("size",100))
),
new CustomAggregationOperation(
new BasicDBObject(
"$group",
new BasicDBObject("_id",null)
.append("ageStdDev",new BasicDBObject("$stdDevSamp","$age"))
)
)
);
And that is the equivalent of the documentation example:
db.users.aggregate(
[
{ "$sample": { "size": 100 } },
{ "$group": { "_id": null, "ageStdDev": { "$stdDevSamp": "$age" } } }
]
)
As an interface for AggregationOperation
the class easily mixes with the implemented helpers:
Aggregation aggregation = newAggregation(
// Using the match helper for the `$match` stage
match(
Criteria.where("age").gte(20).lte(50)
),
// Mixed in with custom classes for the others
new CustomAggregationOperation(
new BasicDBObject("$sample", new BasicDBObject("size",100))
),
new CustomAggregationOperation(
new BasicDBObject(
"$group",
new BasicDBObject("_id",null)
.append("ageStdDev",new BasicDBObject("$stdDevSamp","$age"))
)
)
);
So you can still use features even if there is no "buit in helper" to work out the BSON Object construction for you. You just do the construction yourself.