@Override public TreeSet<DimensionRow> notinFilterOperation(TreeSet<DimensionRow> dimensionRows, ApiFilter filter) { TreeSet<DimensionRow> filteredDimensionRows = new TreeSet<>(dimensionRows); for (DimensionRow dimensionRow : dimensionRows) { String value = dimensionRow.get(filter.getDimensionField()); if (filter.getValues().contains(value)) { filteredDimensionRows.remove(dimensionRow); } } return filteredDimensionRows; }
@Override public TreeSet<DimensionRow> inFilterOperation(TreeSet<DimensionRow> dimensionRows, ApiFilter filter) { return dimensionRows.stream() .filter(row -> filter.getValues().contains(row.get(filter.getDimensionField()))) .collect(Collectors.toCollection(TreeSet<DimensionRow>::new)); }
@Override public TreeSet<DimensionRow> startswithFilterOperation( TreeSet<DimensionRow> dimensionRows, ApiFilter filter ) { TreeSet<DimensionRow> filteredDimensionRows = new TreeSet<>(); // regex string containing all starts with filter values StringBuilder startsWithRegex = new StringBuilder("("); for (String filterValue : filter.getValues()) { startsWithRegex.append(filterValue).append("|"); } startsWithRegex.replace(startsWithRegex.length() - 1, startsWithRegex.length(), ").*"); String startsWithRegexString = startsWithRegex.toString(); for (DimensionRow dimensionRow : dimensionRows) { String value = dimensionRow.get(filter.getDimensionField()); if (value.matches(startsWithRegexString)) { filteredDimensionRows.add(dimensionRow); } } return filteredDimensionRows; }
/** * Contains filter operation. * * @param dimensionRows The unfiltered set of dimension rows * @param filter The api filter * * @return Tree set of DimensionRows */ @Override public TreeSet<DimensionRow> containsFilterOperation(TreeSet<DimensionRow> dimensionRows, ApiFilter filter) { TreeSet<DimensionRow> filteredDimensionRows = new TreeSet<>(); // regex string containing all contains filter values StringBuilder containsRegex = new StringBuilder(".*("); for (String filterValue : filter.getValues()) { containsRegex.append(filterValue).append("|"); } containsRegex.replace(containsRegex.length() - 1, containsRegex.length(), ").*"); for (DimensionRow dimensionRow : dimensionRows) { String value = dimensionRow.get(filter.getDimensionField()); if (value.matches(containsRegex.toString())) { filteredDimensionRows.add(dimensionRow); } } return filteredDimensionRows; }
/** * Take two Api filters which differ only by value sets and union their value sets. * * @param one The first ApiFilter * @param two The second ApiFilter * * @return an ApiFilter with the union of values */ public ApiFilter union(ApiFilter one, ApiFilter two) { if (Objects.equals(one.getDimension(), two.getDimension()) && Objects.equals(one.getDimensionField(), two.getDimensionField()) && Objects.equals(one.getOperation(), two.getOperation()) ) { Set<String> values = Stream.concat( one.getValues().stream(), two.getValues().stream() ) .collect(Collectors.toSet()); return one.withValues(values); } throw new IllegalArgumentException(String.format("Unmergable ApiFilters '%s' and '%s'", one, two)); } }
/** * Validity rules for non-aggregatable dimensions that are only referenced in filters. * A query that references a non-aggregatable dimension in a filter without grouping by this dimension, is valid * only if the requested dimension field is a key for this dimension and only a single value is requested * with an inclusive operator ('in' or 'eq'). * * @return A predicate that determines a given dimension is non aggregatable and also not constrained to one row * per result */ protected static Predicate<ApiFilter> isNonAggregatableInFilter() { return apiFilter -> !apiFilter.getDimensionField().equals(apiFilter.getDimension().getKey()) || apiFilter.getValues().size() != 1 || !( apiFilter.getOperation().equals(DefaultFilterOperation.in) || apiFilter.getOperation().equals(DefaultFilterOperation.eq) ); }
new ImmutableTriple<>(filter.getDimension(), filter.getDimensionField(), filter.getOperation());
/** * Constructor. * * Parses the URL filter Query and generates the ApiFilter object. * * @param filterQuery Expects a URL filter query String in the format: * <code>(dimension name)|(field name)-(operation)[?(value or comma separated values)]?</code> * @param dimensionDictionary cache containing all the valid dimension objects. * * @throws BadFilterException Exception when filter pattern is not matched or when any of its properties are not * @deprecated use {@link ApiFilterGenerator} build method instead */ @Deprecated public ApiFilter( @NotNull String filterQuery, DimensionDictionary dimensionDictionary ) throws BadFilterException { ApiFilter filter = ApiFilterGenerator.build(filterQuery, dimensionDictionary); this.dimension = filter.getDimension(); this.dimensionField = filter.getDimensionField(); this.operation = filter.getOperation(); this.values = filter.getValuesList(); }
/** * Constructor. * * @param filter The filter being recorded */ public Filter(ApiFilter filter) { this.dimension = filter.getDimension().getApiName(); this.field = filter.getDimensionField().getName(); this.operator = filter.getOperation().getName(); this.numberOfValues = filter.getValues().size(); }
String luceneFieldName = DimensionStoreKeyUtils.getColumnKey(filter.getDimensionField().getName()); switch (defaultFilterOp) { case eq: