racerX
racerX

Reputation: 1092

How to use DateOperators in Spring Mongo Data aggregation

We have an aggregation pipeline setup in Spring Data Mongo like so:

MatchOperation matchStage = ...
Fields groupingFields = Fields.fields();
groupingFields.and(name1, target1);
groupingFields.and(name2, target2);
...
GroupOperation groupStage = Aggregation.group(groupingFields);
List<AggregationOperation> aggStages = new ArrayList<>();
aggStages.add(matchStage);
aggStages.add(groupStage);
Aggregation aggregation = Aggregation.newAggregation(aggStages);

Now, we want to be able to use aggregation over dates using Date operators in mongodb. This is fairly straightforward in mongodb, example below:

db.getCollection('Collection').aggregate([
    {"$match": {"state": "XY"}},
    {"$group": {
        "_id": {
            "city": "$city",
            "dayOfYear": {"$dayOfYear": "$date"}
        },
        "totalProfit": {"$sum": "$profit"}
    }}
])

My question is, how can I use the $dayOfYear operator in the Spring pipeline we have. Spring has support for DateOperators like DateOperators.DayOfWeek etc. but I am unable to incorporate it into the pipeline as we have it. How do I modify the groupStage so I can group by various date related parts as required?

Upvotes: 1

Views: 755

Answers (1)

varman
varman

Reputation: 8894

For some operation I used to follow Bson document styles

@Autowired
private MongoTemplate mongoTemplate;

public List<Object> test() {

    Aggregation aggregation = Aggregation.newAggregation(   
        match(Criteria.where("state").is("XY"))
        p-> new Document("$group",
                new Document("_id",
                    new Document("city","$city")
                    .append("dayOfYear",
                        new Document("$dayOfYear", "$date")
                    )
                    
                ).append("totalProfit",
                    new Document("$sum","$$profit")
                )
            )
    ).withOptions(AggregationOptions.builder().allowDiskUse(Boolean.TRUE).build());

    return mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(YOUR_COLLECTION.class), Object.class).getMappedResults();

}

This should work, if the above aggregation you posted is working. You can refer Trick to convert. I haven't tried DateOperator yet. But I'm curious how does it work. I will update if I get to know about it. Until then you have no blockers

Upvotes: 1

Related Questions