private List<Query> buildGroupIntervalQuery(DataSetGroup group) {
    if (group == null || !group.isSelect()) return null;

    List<Query> result = new LinkedList<Query>();
    String sourceId = group.getColumnGroup().getSourceId();
    ColumnType columnType = metadata.getColumnType(sourceId);
    ElasticSearchDataSetDef def = (ElasticSearchDataSetDef) metadata.getDefinition();

    List<Interval> intervals = group.getSelectedIntervalList();
    for (Interval interval : intervals) {
      Query _result = null;
      boolean isLabelCol = ColumnType.LABEL.equals(columnType);
      boolean isNumericCol = ColumnType.NUMBER.equals(columnType);
      boolean isDateCol = ColumnType.DATE.equals(columnType);
      boolean isTextCol = ColumnType.TEXT.equals(columnType);

      if (isTextCol) {
        throw new IllegalArgumentException(
            "Not supported type ["
                + columnType.name()
                + "] for column with id ["
                + sourceId
                + "] using grouping.");
      }

      if (isLabelCol) {
        String filterValue = valueTypeMapper.formatLabel(def, sourceId, interval.getName());
        _result = new Query(sourceId, Query.Type.TERM);
        _result.setParam(Query.Parameter.VALUE.name(), filterValue);
      } else if (isNumericCol || isDateCol) {
        Object maxValue = interval.getMaxValue();
        Object minValue = interval.getMinValue();
        Object value0 =
            isNumericCol
                ? valueTypeMapper.formatNumeric(def, sourceId, (Double) minValue)
                : valueTypeMapper.formatDate(def, sourceId, (Date) minValue);
        Object value1 =
            isNumericCol
                ? valueTypeMapper.formatNumeric(def, sourceId, (Double) maxValue)
                : valueTypeMapper.formatDate(def, sourceId, (Date) maxValue);
        _result = new Query(sourceId, Query.Type.RANGE);
        _result.setParam(Query.Parameter.GT.name(), value0);
        _result.setParam(Query.Parameter.LT.name(), value1);
      }

      result.add(_result);
    }

    return result;
  }
  @Override
  public Query build() {
    if (filters == null || filters.isEmpty()) return null;

    List<Query> queries = new LinkedList<Query>();

    // Build query definition for filter operations.
    for (DataSetFilter filter : filters) {
      Query subQuery = build(filter.getColumnFilterList(), Operator.AND);
      if (subQuery == null) continue;
      queries.add(subQuery);
    }

    // Build query definition for interval group selections.
    for (DataSetGroup group : groups) {
      if (group.isSelect()) {
        List<Query> subQueries = buildGroupIntervalQuery(group);
        if (subQueries != null && !subQueries.isEmpty()) {
          for (Query subQuery : subQueries) {
            queries.add(subQuery);
          }
        }
      }
    }

    Query result = joinQueriesAndFilters(queries, Operator.AND);

    // If result is a filter, wrap into a MATCH_ALL filtered query, as EL aggregations requires
    // working with queries.
    if (result != null && isFilter(result)) {
      Query filtered = new Query(Query.Type.FILTERED);
      Query matchAll = new Query(Query.Type.MATCH_ALL);
      filtered.setParam(Query.Parameter.QUERY.name(), matchAll);
      filtered.setParam(Query.Parameter.FILTER.name(), result);
      return filtered;
    }
    return result;
  }