/** * Default constructor. GSON recommended. */ public Query() { // If no aggregation is provided, the default one is used. Aggregations must be present. aggregation = new Aggregation(); }
/** * Extract a {@link Aggregation.Type#RAW} Aggregation. * * @param size The non-null size from BQL LIMIT clause. * @return A {@link Aggregation.Type#RAW} Aggregation. * @throws NullPointerException when size is null. */ public Aggregation extractRaw(Optional<Long> size) throws NullPointerException { requireNonNull(size); Aggregation raw = new Aggregation(); raw.setType(Aggregation.Type.RAW); size.ifPresent(sizeValue -> raw.setSize(sizeValue.intValue())); return raw; }
/** * Extract a {@link Aggregation.Type#TOP_K} Aggregation. * * @param groupByFields The non-null Set of {@link Expression} in the BQL GROUP BY clause. * @param threshold The non-null Optional of threshold of this TopK aggregation. * @param size The non-null Optional of size of this TopK aggregation. * @return A {@link Aggregation.Type#TOP_K} Aggregation. * @throws NullPointerException when any of groupByFields, threshold and size is null. */ public Aggregation extractTopK(Set<Expression> groupByFields, Optional<Long> threshold, Optional<Long> size) throws NullPointerException { requireNonNull(groupByFields); requireNonNull(threshold); requireNonNull(size); Aggregation topK = new Aggregation(); topK.setType(TOP_K); size.ifPresent(sizeValue -> topK.setSize(sizeValue.intValue())); topK.setFields(getFields(new ArrayList<>(groupByFields))); Map<String, Object> attributes = new HashMap<>(); threshold.ifPresent(min -> attributes.put(THRESHOLD_FIELD, min)); for (Node node : aliases.keySet()) { if (node instanceof FunctionCall) { attributes.put(NEW_NAME_FIELD, getAlias((Expression) node)); } } if (!attributes.isEmpty()) { topK.setAttributes(attributes); } return topK; }
/** * Extract a {@link Aggregation.Type#GROUP} Aggregation. * * @param selectFields The non-null Set of {@link Expression} in the BQL SELECT clause. * @param groupByFields The non-null Set of {@link Expression} in the BQL GROUP BY clause. * @param size The non-null Optional of size of this group aggregation. * @return A {@link Aggregation.Type#GROUP} Aggregation. * @throws NullPointerException when any of selectFields, groupByFields and size is null. * @throws ParsingException when any of selectionField is not grouping function nor in group by clause. */ public Aggregation extractGroup(Set<Expression> selectFields, Set<Expression> groupByFields, Optional<Long> size) throws NullPointerException, ParsingException { requireNonNull(selectFields); requireNonNull(groupByFields); requireNonNull(size); Aggregation group = new Aggregation(); group.setType(GROUP); size.ifPresent(sizeValue -> group.setSize(sizeValue.intValue())); if (!groupByFields.isEmpty()) { group.setFields(getFields(new ArrayList<>(groupByFields))); } Map<String, Object> attributes = getGroupAttributes(selectFields, groupByFields); if (!attributes.isEmpty()) { group.setAttributes(attributes); } return group; }
/** * Extract a {@link Aggregation.Type#COUNT_DISTINCT} Aggregation. * * @param node The non-null COUNT_DISTINCT {@link FunctionCall} expression. * @return A {@link Aggregation.Type#COUNT_DISTINCT} Aggregation. * @throws NullPointerException when node is null. */ public Aggregation extractCountDistinct(FunctionCall node) throws NullPointerException { requireNonNull(node); Aggregation countDistinct = new Aggregation(); countDistinct.setType(COUNT_DISTINCT); countDistinct.setFields(getFields(node.getArguments())); if (aliases.containsKey(node)) { Map<String, Object> attributes = new HashMap<>(); attributes.put(NEW_NAME_FIELD, getAlias(node)); countDistinct.setAttributes(attributes); } return countDistinct; }
/** * Extract a {@link Aggregation.Type#TOP_K} Aggregation. * * @param node The non-null {@link TopK} expression. * @return A {@link Aggregation.Type#TOP_K} Aggregation. * @throws NullPointerException when node is null. */ public Aggregation extractTopKFunction(TopK node) throws NullPointerException { requireNonNull(node); Aggregation topK = new Aggregation(); topK.setType(TOP_K); topK.setSize(node.getSize().intValue()); topK.setFields(getFields(node.getColumns())); Map<String, Object> attributes = new HashMap<>(); node.getThreshold().ifPresent(threshold -> attributes.put(THRESHOLD_FIELD, threshold)); if (aliases.containsKey(node)) { attributes.put(NEW_NAME_FIELD, getAlias(node)); } if (!attributes.isEmpty()) { topK.setAttributes(attributes); } return topK; }
/** * Extract a {@link Aggregation.Type#DISTRIBUTION} Aggregation. * * @param node The non-null {@link Distribution} expression. * @param size The non-null Optional of size of this distribution aggregation. * @return A {@link Aggregation.Type#DISTRIBUTION} Aggregation. * @throws NullPointerException when any of node and size is null. */ public Aggregation extractDistribution(Distribution node, Optional<Long> size) throws NullPointerException { requireNonNull(node); requireNonNull(size); Aggregation distribution = new Aggregation(); distribution.setType(DISTRIBUTION); size.ifPresent(sizeValue -> distribution.setSize(sizeValue.intValue())); distribution.setFields(getFields(node.getColumns())); Map<String, Object> attributes = node.getAttributes(); if (aliases.containsKey(node)) { attributes.put(NEW_NAME_FIELD, getAlias(node)); } distribution.setAttributes(attributes); return distribution; }
@Override @SuppressWarnings("unchecked") public void configure(BulletConfig config) { if (filters != null) { filters = rewriteClauses(filters); filters.forEach(f -> f.configure(config)); } if (projection != null) { projection.configure(config); } // Must have an aggregation if (aggregation == null) { aggregation = new Aggregation(); } aggregation.configure(config); boolean disableWindowing = config.getAs(BulletConfig.WINDOW_DISABLE, Boolean.class); if (disableWindowing) { window = null; } else if (window != null) { window.configure(config); } long durationDefault = config.getAs(BulletConfig.QUERY_DEFAULT_DURATION, Long.class); long durationMax = config.getAs(BulletConfig.QUERY_MAX_DURATION, Long.class); // Null or negative, then default, else min of duration and max. duration = (duration == null || duration <= 0) ? durationDefault : Math.min(duration, durationMax); if (postAggregations != null) { postAggregations.forEach(p -> p.configure(config)); } }