7

I have a function that receive an Aggregation aggregation as a param.

I would like to get all AggregationOperation from aggregation. Is there any way to do it?

public Aggregation newCustomAggregation(Aggregation aggregation, Criteria c) {
    // How to get list operation aggregation there?
    listOperation.push(Aggregation.match(c));
    return Aggregation
            .newAggregation(listOperations);
}

My purpose is new another Aggregation with my custom MatchAggregation.

Ivar
  • 6,138
  • 12
  • 49
  • 61
taile
  • 2,738
  • 17
  • 29
  • How do you plan on using this `newCustomAggregation` function? – chridam Nov 09 '17 at 13:39
  • Hello chridam, I would like to use it for adding dynamic criteria to filter out the result when receiving it as a parameter (similar the way query.addCriteria(...myCriteria)) – taile Nov 09 '17 at 16:21

3 Answers3

5

You can create your own custom aggregation implementation by subclassing the aggregation to access the protected operations field.

Something like

public class CustomAggregation extends Aggregation {
      List<AggregationOperation> getAggregationOperations() {
      return operations;
   }
}

public Aggregation newCustomAggregation(Aggregation aggregation, Criteria c) {
     CustomAggregation customAggregation = (CustomAggregation) aggregation;
     List<AggregationOperation> listOperations = customAggregation.getAggregationOperations();
     listOperations.add(Aggregation.match(c));
     return Aggregation .newAggregation(listOperations);
 }
s7vr
  • 73,656
  • 11
  • 106
  • 127
  • This doesn't answer the question. The question is about getting the list of `AggregationOperation`s from an `Aggregation` instance. This solution gets a list of `AggregationOperation`s from a `CustomAggregation` instance only. For any other `Aggregation` it just throws a `ClassCastException`. I don't see much sense in that. – jannis Nov 23 '17 at 08:56
  • @jannis As you already noted there is no way to get `operations` field from `Aggregation` class. I have provided answer where op can subclass the `Aggregation` class to access `protected` `operations` field and expose the field through getter. Let me know which part is still not clear. – s7vr Nov 24 '17 at 11:21
  • I'm not saying it's not clear. I'm saying it doesn't answer the question. – jannis Nov 24 '17 at 11:32
4

Short answer: No, there's no GOOD way to do it.

There is no 'easy' way of getting the AggregationOperation list from outside an Aggregation instance - operations is a protected property of Aggregation class.

You could easily get it with reflection but such code would be fragile and expensive to maintain. Probably there's a good reason for this property to remain protected. You could ask about this in Spring-MongoDB's JIRA. I assume that there is an alternative approach to this.

You could of course change your method to take a collection of AggregationOperation as parameter but there's too liitle information in your post to say if this solution is feasible in your case.

jannis
  • 4,843
  • 1
  • 23
  • 53
2

Aggregation has a property operations which will give you all applied operation in Aggregation.

 protected List<AggregationOperation>   allOperations = aggregation.operations ;

will give you all applied operations.

Mehraj Malik
  • 14,872
  • 15
  • 58
  • 85