private Query constructQuery() { Query query = new Query(); query.setAggregation(aggregation); query.setDuration(duration); query.setFilters(filters); query.setProjection(projection); query.setWindow(window); query.setPostAggregations(postAggregations); return query; }
/** * Parses a Query out of the query string. * * @param queryString The String version of the query. * @param config Additional configuration for the query. * * @return The parsed, configured Query. * @throws com.google.gson.JsonParseException if there was an issue parsing the query. */ public static Query parse(String queryString, BulletConfig config) { Query query = GSON.fromJson(queryString, Query.class); query.configure(config); return query; } }
/** * Returns true if this running query has timed out. In other words, it returns whether this has been running * longer than the query duraton. * * @return A boolean denoting whether this query has timed out. */ public boolean isTimedOut() { // Never add to query.getDuration since it can be infinite (Long.MAX_VALUE) return System.currentTimeMillis() - startTime >= query.getDuration(); }
private void addTransientFieldsFor(PostStrategy postStrategy) { Projection projection = runningQuery.getQuery().getProjection(); Aggregation aggregation = runningQuery.getQuery().getAggregation(); if (aggregation.getType() == Aggregation.Type.RAW && projection != null) { Map<String, String> projectionFields = projection.getFields(); if (projectionFields != null) { postStrategy.getRequiredFields().stream().filter(field -> !projectionFields.containsValue(field)) .forEach(field -> transientFields.put(field, field)); } } } }
Strategy strategy = AggregationOperations.findStrategy(query.getAggregation(), config); errors = strategy.initialize(); if (errors.isPresent()) { if (query.getPostAggregations() != null) { postStrategies = query.getPostAggregations().stream().map(PostAggregationOperations::findPostStrategy).collect(Collectors.toList()); for (PostStrategy postStrategy : postStrategies) { errors = postStrategy.initialize();
private Clause rewriteClause(Clause clause) { Clause toReturn = clause; if (clause instanceof LogicalClause) { LogicalClause logical = ((LogicalClause) clause); logical.setClauses(rewriteClauses(logical.getClauses())); } else if (clause instanceof StringFilterClause) { toReturn = new ObjectFilterClause((StringFilterClause) clause); } return toReturn; } }
/** * Returns if this query should buffer before emitting the final results. You can use this to wait for the final * results in your Join or Combine stage after a query is {@link #isDone()}. * * @return A boolean that is true if the query results should be buffered in the Join phase. */ public boolean shouldBuffer() { Window window = runningQuery.getQuery().getWindow(); boolean noWindow = window == null; // Only buffer if there is no window (including Raw) or if it's a record based window. return noWindow || !window.isTimeBased(); }
private boolean filter(BulletRecord record) { List<Clause> filters = runningQuery.getQuery().getFilters(); // Add the record if we have no filters if (filters == null) { return true; } // Otherwise short circuit evaluate till the first filter fails. Filters are ANDed. return filters.stream().allMatch(c -> FilterOperations.perform(record, c)); }
@Override public Optional<List<BulletError>> initialize() { start(); return query.initialize(); }
private BulletRecord project(BulletRecord record) { Projection projection = runningQuery.getQuery().getProjection(); return projection != null ? ProjectionOperations.project(record, projection, transientFields, provider) : record; }
@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)); } }
Window window = query.getWindow(); if (window == null) { return new Basic(strategy, null, config);
/** * {@inheritDoc} * * This partitioner ensures that queries are not stored in duplicate by returning only key for a query (the list * that is returned is of size 1). * * @param query {@inheritDoc} * @return {@inheritDoc} */ @Override public Set<String> getKeys(Query query) { Objects.requireNonNull(query); List<Clause> filters = query.getFilters(); // If no filters or has non ANDs, default partition if (filters == null || filters.isEmpty() || hasNonANDLogicals(filters)) { return defaultKeys; } // For each unique field, get all the FilterClauses that define an operation on it. Map<String, List<FilterClause>> fieldFilters = new HashMap<>(); filters.forEach(c -> this.mapFieldToFilters(c, fieldFilters)); // If not one equality filter per field and not one value per filter, default partition if (fieldFilters.values().stream().anyMatch(this::hasInvalidFilterClauses)) { return defaultKeys; } // Generate key in fields order and pad with NO_FIELD if no mapping present String key = fields.stream().map(fieldFilters::get).map(this::getFilterValue).collect(Collectors.joining(delimiter)); // For the SimpleEqualityPartitioner, the query is mapped to exactly one key only. return Collections.singleton(key); }