@Override
    public void process(Consumer<Bson> consumer) {
      // {$group: {_id: {STATE: '$STATE', CITY: '$CITY'}, C: {$sum: 1}}}
      // {$project: {_id: 0, STATE: '$_id.STATE', CITY: '$_id.CITY', C: '$C'}}
      final BsonDocument id = new BsonDocument();
      final List<BsonField> accumulators = new ArrayList<>();
      final BsonDocument project = new BsonDocument();

      // $group
      query.groupBy().forEach(groupBy -> {
        String alias = naming.get(extractPath(groupBy));
        id.put(alias, new BsonString("$" + alias));
      });

      // $project part
      for (Expression expr: query.projections()) {
        final String alias = naming.get(extractPath(expr));
        final String uniq = projectionNaming.name(expr);
        if (query.groupBy().contains(expr)) {
          project.put(alias, new BsonString(id.size() == 1 ? "$_id" : "$_id." + alias));
        } else if (expr instanceof Call) {
          // actual aggregation sum / max / min count etc.
          accumulators.add(accumulator(uniq, expr));
          project.put(uniq, new BsonString("$" + uniq));
        } else {
          // simple projection
          project.put(uniq, new BsonString("$" + uniq));
        }
      }

      if (query.distinct() && !id.isEmpty()) {
        BsonValue groupId = id.size() == 1 ? id.values().iterator().next() : id;
        consumer.accept(Aggregates.group(groupId));
      }

      if (!accumulators.isEmpty()) {
        BsonValue groupId = id.size() == 1 ? id.values().iterator().next() : id;
        consumer.accept(Aggregates.group(groupId, accumulators));
      }

      if (!project.isEmpty()) {
        consumer.accept(Aggregates.project(project));
      }
    }
Converts query of type {@code select distinct a, b, c from table} to {@code select a, b, c from table group by a, b, c}
so same pipelines (like {@link Group}) can be (re-)used. Does nothing if this is not a {@code distinct} query.
@param query query to be converted
@return new version of the query with projections copied to {@code groupBy} list or unmodified query.
@throws UnsupportedOperationException if query is "distinct" and {@code groupBy} is not empty
criteria/mongo/src/org/immutables/criteria/mongo/AggregationQuery.java