use of org.hisp.dhis.common.DimensionalObject in project dhis2-core by dhis2.
the class AnalyticsUtils method getAggregatedDataValueMapping.
/**
* Generates a mapping where the key represents the dimensional item identifiers
* concatenated by {@link DimensionalObject#DIMENSION_SEP} and the value is
* the corresponding aggregated data value based on the given grid. Assumes
* that the value column is the last column in the grid.
*
* @param grid the grid.
* @return a mapping between item identifiers and aggregated values.
*/
public static Map<String, Object> getAggregatedDataValueMapping(Grid grid) {
Map<String, Object> map = new HashMap<>();
int metaCols = grid.getWidth() - 1;
int valueIndex = grid.getWidth() - 1;
for (List<Object> row : grid.getRows()) {
StringBuilder key = new StringBuilder();
for (int index = 0; index < metaCols; index++) {
key.append(row.get(index)).append(DIMENSION_SEP);
}
key.deleteCharAt(key.length() - 1);
Object value = row.get(valueIndex);
map.put(key.toString(), value);
}
return map;
}
use of org.hisp.dhis.common.DimensionalObject in project dhis2-core by dhis2.
the class DefaultQueryPlanner method groupByDaysInPeriod.
/**
* Groups the given query into sub queries based on the number of days in the
* aggregation period. This only applies if the aggregation type is
* {@link AggregationType#AVERAGE_SUM_INT} and the query has at least one period as
* dimension option. This is necessary since the number of days in the aggregation
* period is part of the expression for aggregating the value.
*
* @param params the data query parameters.
* @return a list of {@link DataQueryParams}.
*/
private List<DataQueryParams> groupByDaysInPeriod(DataQueryParams params) {
List<DataQueryParams> queries = new ArrayList<>();
if (params.getPeriods().isEmpty() || !params.isAggregationType(AggregationType.AVERAGE_SUM_INT)) {
queries.add(DataQueryParams.newBuilder(params).build());
return queries;
}
ListMap<Integer, DimensionalItemObject> daysPeriodMap = QueryPlannerUtils.getDaysPeriodMap(params.getPeriods());
DimensionalObject periodDim = params.getDimension(PERIOD_DIM_ID);
for (Integer days : daysPeriodMap.keySet()) {
DataQueryParams query = DataQueryParams.newBuilder(params).addOrSetDimensionOptions(periodDim.getDimension(), periodDim.getDimensionType(), periodDim.getDimensionName(), daysPeriodMap.get(days)).build();
queries.add(query);
}
if (queries.size() > 1) {
log.debug(String.format("Split on days in period: %d", queries.size()));
}
return queries;
}
use of org.hisp.dhis.common.DimensionalObject in project dhis2-core by dhis2.
the class DefaultQueryPlanner method splitByDimension.
// -------------------------------------------------------------------------
// Supportive methods
// -------------------------------------------------------------------------
/**
* Splits the given list of queries in sub queries on the given dimension.
*/
private DataQueryGroups splitByDimension(DataQueryGroups queryGroups, String dimension, int optimalQueries) {
int optimalForSubQuery = MathUtils.divideToFloor(optimalQueries, queryGroups.getLargestGroupSize());
List<DataQueryParams> subQueries = new ArrayList<>();
for (DataQueryParams query : queryGroups.getAllQueries()) {
DimensionalObject dim = query.getDimension(dimension);
List<DimensionalItemObject> values = null;
if (dim == null || (values = dim.getItems()) == null || values.isEmpty()) {
subQueries.add(DataQueryParams.newBuilder(query).build());
continue;
}
List<List<DimensionalItemObject>> valuePages = new PaginatedList<>(values).setNumberOfPages(optimalForSubQuery).getPages();
for (List<DimensionalItemObject> valuePage : valuePages) {
DataQueryParams subQuery = DataQueryParams.newBuilder(query).withDimensionOptions(dim.getDimension(), valuePage).build();
subQueries.add(subQuery);
}
}
if (subQueries.size() > queryGroups.getAllQueries().size()) {
log.debug(String.format("Split on dimension %s: %d", dimension, (subQueries.size() / queryGroups.getAllQueries().size())));
}
return DataQueryGroups.newBuilder().withQueries(subQueries).build();
}
use of org.hisp.dhis.common.DimensionalObject in project dhis2-core by dhis2.
the class DefaultQueryPlanner method groupByAggregationType.
/**
* Groups the given query in sub queries based on the aggregation type of its
* data elements. The aggregation type can be sum, average aggregation or
* average disaggregation. Sum means that the data elements have sum aggregation
* operator. Average aggregation means that the data elements have the average
* aggregation operator and that the period type of the data elements have
* higher or equal frequency than the aggregation period type. Average disaggregation
* means that the data elements have the average aggregation operator and
* that the period type of the data elements have lower frequency than the
* aggregation period type. Average bool means that the data elements have the
* average aggregation operator and the bool value type.
* <p>
* If no data elements are present, the aggregation type will be determined
* based on the first data element in the first data element group in the
* first data element group set in the query.
* <p>
* If the aggregation type is already set/overridden in the request, the
* query will be returned unchanged. If there are no data elements or data
* element group sets specified the aggregation type will fall back to sum.
*
* @param params the data query parameters.
* @return a list of {@link DataQueryParams}.
*/
private List<DataQueryParams> groupByAggregationType(DataQueryParams params) {
List<DataQueryParams> queries = new ArrayList<>();
if (!params.getDataElements().isEmpty()) {
ListMap<AggregationType, DimensionalItemObject> aggregationTypeDataElementMap = QueryPlannerUtils.getAggregationTypeDataElementMap(params);
for (AggregationType aggregationType : aggregationTypeDataElementMap.keySet()) {
DataQueryParams query = DataQueryParams.newBuilder(params).withDataElements(aggregationTypeDataElementMap.get(aggregationType)).withAggregationType(aggregationType).build();
queries.add(query);
}
} else if (!params.getDataElementGroupSets().isEmpty()) {
DimensionalObject degs = params.getDataElementGroupSets().get(0);
DataElementGroup deg = (DataElementGroup) (degs.hasItems() ? degs.getItems().get(0) : null);
AggregationType aggregationType = ObjectUtils.firstNonNull(params.getAggregationType(), SUM);
if (deg != null && !deg.getMembers().isEmpty()) {
PeriodType periodType = PeriodType.getPeriodTypeByName(params.getPeriodType());
aggregationType = ObjectUtils.firstNonNull(params.getAggregationType(), deg.getAggregationType());
aggregationType = QueryPlannerUtils.getAggregationType(deg.getValueType(), aggregationType, periodType, deg.getPeriodType());
}
DataQueryParams query = DataQueryParams.newBuilder(params).withAggregationType(aggregationType).build();
queries.add(query);
} else {
DataQueryParams query = DataQueryParams.newBuilder(params).withAggregationType(ObjectUtils.firstNonNull(params.getAggregationType(), SUM)).build();
queries.add(query);
}
if (queries.size() > 1) {
log.debug(String.format("Split on aggregation type: %d", queries.size()));
}
return queries;
}
use of org.hisp.dhis.common.DimensionalObject in project dhis2-core by dhis2.
the class DataQueryParams method retainDataDimensions.
/**
* Retains only dimensions of the given data dimension item types.
*
* @param itemTypes the array of data dimension item types.
*/
private DataQueryParams retainDataDimensions(DataDimensionItemType... itemTypes) {
DimensionalObject dimension = getDimensionOrFilter(DATA_X_DIM_ID);
List<DimensionalItemObject> items = new ArrayList<>();
for (DataDimensionItemType itemType : itemTypes) {
items.addAll(AnalyticsUtils.getByDataDimensionItemType(itemType, dimension.getItems()));
}
dimension.getItems().clear();
dimension.getItems().addAll(items);
return this;
}
Aggregations